Code Formatting

This commit is contained in:
2025-12-05 16:02:49 +05:30
parent aef82237ac
commit 72a2c56392
10 changed files with 962 additions and 985 deletions

View File

@@ -84,4 +84,4 @@ class LimitService {
} }
return response.toString(); return response.toString();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ class _AllAccountsScreenState extends State<AllAccountsScreen> {
// In a real app, this should be moved to a utility/helper class. // In a real app, this should be moved to a utility/helper class.
if (accountType == null || accountType.isEmpty) return 'N/A'; if (accountType == null || accountType.isEmpty) return 'N/A';
switch (accountType.toLowerCase()) { switch (accountType.toLowerCase()) {
case 'sa': case 'sa':
return AppLocalizations.of(context).savingsAccount; return AppLocalizations.of(context).savingsAccount;
case 'sb': case 'sb':
return AppLocalizations.of(context).savingsAccount; return AppLocalizations.of(context).savingsAccount;
@@ -36,7 +36,7 @@ class _AllAccountsScreenState extends State<AllAccountsScreen> {
return "Cash Credit Account"; return "Cash Credit Account";
case 'od': case 'od':
return "Overdraft Account"; return "Overdraft Account";
default: default:
return AppLocalizations.of(context).unknownAccount; return AppLocalizations.of(context).unknownAccount;
} }
} }
@@ -52,19 +52,19 @@ class _AllAccountsScreenState extends State<AllAccountsScreen> {
const SizedBox(height: 16.0), // Added space below the app bar const SizedBox(height: 16.0), // Added space below the app bar
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
itemCount: widget.users.length, itemCount: widget.users.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final user = widget.users[index]; final user = widget.users[index];
return Padding( return Padding(
padding: padding: const EdgeInsets.symmetric(
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), horizontal: 16.0, vertical: 8.0),
child: _buildAccountCard(user), child: _buildAccountCard(user),
); );
}, },
), ),
), // Closing Expanded ), // Closing Expanded
], // Closing Column ], // Closing Column
), ),
); );
} }

View File

@@ -104,7 +104,9 @@ class _CustomerInfoScreenState extends State<CustomerInfoScreen> {
width: double.infinity, width: double.infinity,
child: CupertinoSlidingSegmentedControl<int>( child: CupertinoSlidingSegmentedControl<int>(
groupValue: _selectedCard, groupValue: _selectedCard,
thumbColor: Theme.of(context).colorScheme.onPrimary, // Set selected switch color to theme primary color thumbColor: Theme.of(context)
.colorScheme
.onPrimary, // Set selected switch color to theme primary color
onValueChanged: (int? newValue) { onValueChanged: (int? newValue) {
if (newValue != null) { if (newValue != null) {
setState(() { setState(() {
@@ -112,14 +114,18 @@ class _CustomerInfoScreenState extends State<CustomerInfoScreen> {
}); });
} }
}, },
children: { children: {
0: Padding( 0: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), padding: const EdgeInsets.symmetric(
child: Text(AppLocalizations.of(context).personaldetails), horizontal: 20, vertical: 10),
child: Text(
AppLocalizations.of(context).personaldetails),
), ),
1: Padding( 1: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), padding: const EdgeInsets.symmetric(
child: Text(AppLocalizations.of(context).kycdetails), horizontal: 20, vertical: 10),
child:
Text(AppLocalizations.of(context).kycdetails),
), ),
}, },
), ),

View File

@@ -9,7 +9,6 @@ import 'package:kmobile/features/accounts/screens/all_accounts_screen.dart';
import 'package:kmobile/features/auth/controllers/auth_cubit.dart'; import 'package:kmobile/features/auth/controllers/auth_cubit.dart';
import 'package:kmobile/features/auth/controllers/auth_state.dart'; import 'package:kmobile/features/auth/controllers/auth_state.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/cheque/screens/cheque_management_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/fund_transfer/screens/fund_transfer_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/fund_transfer_screen.dart';
@@ -65,8 +64,6 @@ class _DashboardScreenState extends State<DashboardScreen>
}); });
} }
Widget _buildAccountCard(User user, bool isSelected) { Widget _buildAccountCard(User user, bool isSelected) {
final theme = Theme.of(context); final theme = Theme.of(context);
final bool isCardVisible = _visibilityMap[user.accountNo] ?? false; final bool isCardVisible = _visibilityMap[user.accountNo] ?? false;
@@ -78,143 +75,143 @@ class _DashboardScreenState extends State<DashboardScreen>
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
scale: scale, scale: scale,
child: Container( child: Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 18, horizontal: 18,
vertical: 10, vertical: 10,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF01A04C), color: const Color(0xFF01A04C),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Top section with account type and number (no refresh button here) // Top section with account type and number (no refresh button here)
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
getFullAccountType(user.accountType), getFullAccountType(user.accountType),
style: TextStyle( style: TextStyle(
color: theme.colorScheme.onPrimary, color: theme.colorScheme.onPrimary,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
),
), ),
Text( ),
user.accountNo ?? 'N/A', Text(
style: TextStyle( user.accountNo ?? 'N/A',
color: theme.colorScheme.onPrimary, style: TextStyle(
fontSize: 14, color: theme.colorScheme.onPrimary,
fontWeight: FontWeight.w700, fontSize: 14,
), fontWeight: FontWeight.w700,
overflow: TextOverflow.ellipsis,
), ),
], overflow: TextOverflow.ellipsis,
),
],
),
),
if (isSelected) // Show logo only if card is selected
CircleAvatar(
radius: 20,
backgroundColor: Colors.white,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: ClipOval(
child: Image.asset(
'assets/images/logo.png',
width: 30,
height: 30,
fit: BoxFit.cover,
),
),
), ),
), ),
if (isSelected) // Show logo only if card is selected ],
CircleAvatar( ),
radius: 20, const Spacer(),
backgroundColor: Colors.white, // Bottom section with balance and combined toggle/refresh
child: Padding( Row(
padding: const EdgeInsets.all(2.0), mainAxisAlignment: MainAxisAlignment.start,
child: ClipOval( children: [
child: Image.asset( if (isRefreshing && isSelected)
'assets/images/logo.png', Expanded(child: _buildBalanceShimmer())
width: 30, else
height: 30, Expanded(
fit: BoxFit.cover, child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Row(
children: [
Text(
"",
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: 40,
fontWeight: FontWeight.w700,
),
), ),
), Text(
isCardVisible
? user.currentBalance ?? '0.00'
: '*****',
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: 40,
fontWeight: FontWeight.w700,
),
),
],
), ),
), ),
], ),
), const SizedBox(width: 10), // A steady space
const Spacer(), if (isSelected) // Only show toggle for selected card
// Bottom section with balance and combined toggle/refresh InkWell(
Row( onTap: () async {
mainAxisAlignment: MainAxisAlignment.start, if (isRefreshing)
children: [ return; // Prevent taps while refreshing
if (isRefreshing && isSelected) final accountNo = user.accountNo;
Expanded(child: _buildBalanceShimmer()) if (accountNo == null) return;
else
Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Row(
children: [
Text(
"",
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: 40,
fontWeight: FontWeight.w700,
),
),
Text(
isCardVisible
? user.currentBalance ?? '0.00'
: '*****',
style: TextStyle(
color: theme.colorScheme.onPrimary,
fontSize: 40,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
const SizedBox(width: 10), // A steady space
if (isSelected) // Only show toggle for selected card
InkWell(
onTap: () async {
if (isRefreshing)
return; // Prevent taps while refreshing
final accountNo = user.accountNo;
if (accountNo == null) return;
final bool currentVisibility = final bool currentVisibility =
_visibilityMap[accountNo] ?? false; _visibilityMap[accountNo] ?? false;
if (!currentVisibility) { if (!currentVisibility) {
// If hidden, refresh data and then show the balance // If hidden, refresh data and then show the balance
await _refreshAccountData(context); await _refreshAccountData(context);
if (mounted) { if (mounted) {
setState(() {
_visibilityMap[accountNo] = true;
});
}
} else {
// If visible, just hide it
setState(() { setState(() {
_visibilityMap[accountNo] = false; _visibilityMap[accountNo] = true;
}); });
} }
}, } else {
child: Padding( // If visible, just hide it
padding: const EdgeInsets.all(8.0), setState(() {
child: Icon( _visibilityMap[accountNo] = false;
isCardVisible });
? Symbols.visibility_lock }
: Symbols.visibility, },
color: theme.scaffoldBackgroundColor, child: Padding(
weight: 800, padding: const EdgeInsets.all(8.0),
), child: Icon(
isCardVisible
? Symbols.visibility_lock
: Symbols.visibility,
color: theme.scaffoldBackgroundColor,
weight: 800,
), ),
), ),
], ),
), ],
const Spacer(), ),
], const Spacer(),
), ],
), ),
), ),
),
); );
} }
@@ -296,7 +293,7 @@ class _DashboardScreenState extends State<DashboardScreen>
return "Cash Credit Account"; return "Cash Credit Account";
case 'od': case 'od':
return "Overdraft Account"; return "Overdraft Account";
default: default:
return AppLocalizations.of(context).unknownAccount; return AppLocalizations.of(context).unknownAccount;
} }
} }
@@ -346,21 +343,19 @@ class _DashboardScreenState extends State<DashboardScreen>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final authState = context.read<AuthCubit>().state; final authState = context.read<AuthCubit>().state;
String mobileNumberToPass = ''; String mobileNumberToPass = '';
String customerNo = ''; String customerNo = '';
String customerName = ''; String customerName = '';
if (authState is Authenticated) { if (authState is Authenticated) {
if (selectedAccountIndex >= 0 && if (selectedAccountIndex >= 0 &&
selectedAccountIndex < authState.users.length) { selectedAccountIndex < authState.users.length) {
mobileNumberToPass = mobileNumberToPass =
authState.users[selectedAccountIndex].mobileNo ?? ''; authState.users[selectedAccountIndex].mobileNo ?? '';
customerNo = customerNo = authState.users[selectedAccountIndex].cifNumber ?? '';
authState.users[selectedAccountIndex].cifNumber ?? ''; customerName = authState.users[selectedAccountIndex].name ?? '';
customerName = }
authState.users[selectedAccountIndex].name ?? ''; }
}
}
return BlocListener<AuthCubit, AuthState>( return BlocListener<AuthCubit, AuthState>(
listener: (context, state) async { listener: (context, state) async {
if (state is Authenticated && !_biometricPromptShown) { if (state is Authenticated && !_biometricPromptShown) {
@@ -416,8 +411,6 @@ class _DashboardScreenState extends State<DashboardScreen>
child: InkWell( child: InkWell(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@@ -431,7 +424,7 @@ class _DashboardScreenState extends State<DashboardScreen>
child: const CircleAvatar( child: const CircleAvatar(
radius: 21, radius: 21,
child: Icon( child: Icon(
Symbols.person, Symbols.person,
size: 30, size: 30,
), ),
), ),
@@ -454,8 +447,7 @@ class _DashboardScreenState extends State<DashboardScreen>
// firsttime load // firsttime load
if (!_txInitialized) { if (!_txInitialized) {
_txInitialized = true; _txInitialized = true;
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {});
});
} }
_pageController ??= PageController( _pageController ??= PageController(
initialPage: selectedAccountIndex, initialPage: selectedAccountIndex,
@@ -489,11 +481,11 @@ class _DashboardScreenState extends State<DashboardScreen>
child: PageView.builder( child: PageView.builder(
clipBehavior: Clip.none, clipBehavior: Clip.none,
controller: _pageController, controller: _pageController,
itemCount: users.length, // Keep this to show adjacent cards itemCount:
users.length, // Keep this to show adjacent cards
onPageChanged: (int newIndex) async { onPageChanged: (int newIndex) async {
if (newIndex == selectedAccountIndex) if (newIndex == selectedAccountIndex) return;
return;
// Hide the balance of the old card when scrolling away // Hide the balance of the old card when scrolling away
final oldAccountNo = final oldAccountNo =
@@ -508,10 +500,8 @@ class _DashboardScreenState extends State<DashboardScreen>
}, },
itemBuilder: (context, index) { itemBuilder: (context, index) {
final user = users[index]; final user = users[index];
final isSelected = final isSelected = index == selectedAccountIndex;
index == selectedAccountIndex; return _buildAccountCard(user, isSelected);
return _buildAccountCard(
user, isSelected);
}, },
), ),
), ),
@@ -524,7 +514,8 @@ class _DashboardScreenState extends State<DashboardScreen>
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => AllAccountsScreen(users: users), builder: (context) =>
AllAccountsScreen(users: users),
), ),
); );
}, },
@@ -625,8 +616,8 @@ class _DashboardScreenState extends State<DashboardScreen>
selectedIndex: selectedAccountIndex, selectedIndex: selectedAccountIndex,
))); )));
}), }),
_buildQuickLink(Icons.location_pin, AppLocalizations.of(context).branchlocator, _buildQuickLink(Icons.location_pin,
() { AppLocalizations.of(context).branchlocator, () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@@ -658,12 +649,11 @@ class _DashboardScreenState extends State<DashboardScreen>
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) => ProfileScreen(
ProfileScreen( mobileNumber: mobileNumberToPass,
mobileNumber: mobileNumberToPass, customerNo: customerNo,
customerNo: customerNo, customerName: customerName),
customerName: customerName), ),
),
); );
}, },
disable: false, disable: false,
@@ -684,32 +674,6 @@ class _DashboardScreenState extends State<DashboardScreen>
); );
} }
List<Widget> _buildTransactionShimmer() {
final theme = Theme.of(context);
return List.generate(3, (i) {
return ListTile(
leading: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: CircleAvatar(
radius: 12, backgroundColor: theme.scaffoldBackgroundColor),
),
title: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
height: 10, width: 100, color: theme.scaffoldBackgroundColor),
),
subtitle: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
height: 8, width: 60, color: theme.scaffoldBackgroundColor),
),
);
});
}
Widget _buildQuickLink( Widget _buildQuickLink(
IconData icon, IconData icon,
String label, String label,

View File

@@ -43,7 +43,8 @@ class FundTransferScreen extends StatelessWidget {
child: FundTransferManagementTile( child: FundTransferManagementTile(
icon: Symbols.person, icon: Symbols.person,
label: "Self Pay", label: "Self Pay",
subtitle: AppLocalizations.of(context).ftselfpaysubtitle, subtitle:
AppLocalizations.of(context).ftselfpaysubtitle,
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
@@ -86,7 +87,8 @@ class FundTransferScreen extends StatelessWidget {
child: FundTransferManagementTile( child: FundTransferManagementTile(
icon: Symbols.output_circle, icon: Symbols.output_circle,
label: AppLocalizations.of(context).outsideBank, label: AppLocalizations.of(context).outsideBank,
subtitle: AppLocalizations.of(context).ftoutsidesubtitle, subtitle:
AppLocalizations.of(context).ftoutsidesubtitle,
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,

View File

@@ -45,11 +45,9 @@ class _ChangeLimitOTPScreenState extends State<ChangeLimitOTPScreen> {
double.parse(widget.newLimit), double.parse(widget.newLimit),
); );
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
const SnackBar( content: Text("Limit has been Changed"),
content: Text("Limit has been Changed"), ));
)
);
// Navigate back to profile or login // Navigate back to profile or login
Navigator.of(context).popUntil((route) => route.isFirst); Navigator.of(context).popUntil((route) => route.isFirst);

View File

@@ -172,241 +172,242 @@ class _ProfileScreenState extends State<ProfileScreen> {
title: Text(loc.profile), title: Text(loc.profile),
elevation: 0, elevation: 0,
), ),
body: Stack( body: Stack(
children: [ children: [
ListView( ListView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
children: [ children: [
// ===== Profile Header ===== // ===== Profile Header =====
Card( Card(
child: Padding( child: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Row( child: Row(
children: [
// Avatar
Container(
width: 56,
height: 56,
child: const CircleAvatar(
radius: 50,
child: Icon(
Symbols.person,
size: 56,
),
),
),
const SizedBox(width: 12),
// Name + mobile
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Avatar Text(
Container( // If you want to show the user's name instead, replace below.
width: 56, widget.customerName,
height: 56, style: theme.textTheme.titleLarge?.copyWith(
child: const CircleAvatar( fontWeight: FontWeight.w600,
radius: 50,
child: Icon(
Symbols.person,
size: 56,
),
), ),
), ),
const SizedBox(width: 12), const SizedBox(height: 4),
// Name + mobile Text(
Expanded( widget.customerNo,
child: Column( style: theme.textTheme.bodyMedium?.copyWith(
crossAxisAlignment: CrossAxisAlignment.start, color: theme.colorScheme.onSurface
children: [ .withOpacity(0.7),
Text(
// If you want to show the user's name instead, replace below.
widget.customerName,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 4),
Text(
widget.customerNo,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurface
.withOpacity(0.7),
),
),
],
), ),
), ),
], ],
), ),
), ),
), ],
),
const SizedBox(height: 16),
// ===== Section: Settings =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"Settings",
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
_SectionTile(
leadingIcon: Icons.settings,
title: loc.preferences,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PreferenceScreen(),
),
);
},
),
_SectionTile(
leadingIcon: Icons.security,
title: loc.securitySettings,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecuritySettingsScreen(
mobileNumber: widget.mobileNumber,
),
),
);
},
),
_SectionTile(
leadingIcon: Icons.currency_rupee,
title: loc.dailylimit,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DailyLimitScreen(mobileNumber: widget.mobileNumber),
),
);
},
),
Card(
child: SwitchListTile(
title: Text(loc.enableFingerprintLogin),
value: _isBiometricEnabled,
onChanged: (bool value) {
_handleBiometricToggle(value);
},
secondary: const Icon(Icons.fingerprint),
contentPadding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
),
),
const SizedBox(height: 16),
const Divider(height: 24),
// ===== Section: Security & App =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
loc.appVersion,
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
// Fingerprint toggle inside a styled container
Card(
child: ListTile(
leading: const Icon(Icons.smartphone),
title: Text(loc.appVersion),
trailing: FutureBuilder<String>(
future: _getAppVersion(),
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
);
} else if (snapshot.hasError) {
return Text(loc.error);
} else {
return Text(
snapshot.data ?? "N/A",
);
}
},
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
const SizedBox(height: 16),
const Divider(height: 24),
// ===== Section: Actions =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"Exit",
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
_SectionTile(
leadingIcon: Icons.exit_to_app,
title: loc.logout,
trailChevron: false, // action tile, no chevron
onTap: () async {
final shouldExit = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text(loc.logout),
content: Text(loc.logoutCheck),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(loc.no),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text(loc.yes),
),
],
),
);
if (shouldExit == true) {
if (Platform.isAndroid) {
SystemNavigator.pop();
}
exit(0);
}
},
),
_SectionTile(
leadingIcon: Icons.logout,
title: loc.deregister,
trailChevron: false,
onTap: () async {
final shouldLogout = await showDialog<bool>(
context: context,
builder: (_) => const LogoutDialog(),
);
if (shouldLogout == true) {
await _handleLogout(context);
}
},
),
const SizedBox(height: 24),
],
), ),
], ),
), );
const SizedBox(height: 16),
// ===== Section: Settings =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"Settings",
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
_SectionTile(
leadingIcon: Icons.settings,
title: loc.preferences,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PreferenceScreen(),
),
);
},
),
_SectionTile(
leadingIcon: Icons.security,
title: loc.securitySettings,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecuritySettingsScreen(
mobileNumber: widget.mobileNumber,
),
),
);
},
),
_SectionTile(
leadingIcon: Icons.currency_rupee,
title: loc.dailylimit,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DailyLimitScreen(mobileNumber: widget.mobileNumber),
),
);
},
),
Card(
child: SwitchListTile(
title: Text(loc.enableFingerprintLogin),
value: _isBiometricEnabled,
onChanged: (bool value) {
_handleBiometricToggle(value);
},
secondary: const Icon(Icons.fingerprint),
contentPadding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
),
),
const SizedBox(height: 16),
const Divider(height: 24),
// ===== Section: Security & App =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
loc.appVersion,
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
// Fingerprint toggle inside a styled container
Card(
child: ListTile(
leading: const Icon(Icons.smartphone),
title: Text(loc.appVersion),
trailing: FutureBuilder<String>(
future: _getAppVersion(),
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
);
} else if (snapshot.hasError) {
return Text(loc.error);
} else {
return Text(
snapshot.data ?? "N/A",
);
}
},
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
const SizedBox(height: 16),
const Divider(height: 24),
// ===== Section: Actions =====
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"Exit",
style: theme.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
),
const SizedBox(height: 8),
_SectionTile(
leadingIcon: Icons.exit_to_app,
title: loc.logout,
trailChevron: false, // action tile, no chevron
onTap: () async {
final shouldExit = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text(loc.logout),
content: Text(loc.logoutCheck),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(loc.no),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text(loc.yes),
),
],
),
);
if (shouldExit == true) {
if (Platform.isAndroid) {
SystemNavigator.pop();
}
exit(0);
}
},
),
_SectionTile(
leadingIcon: Icons.logout,
title: loc.deregister,
trailChevron: false,
onTap: () async {
final shouldLogout = await showDialog<bool>(
context: context,
builder: (_) => const LogoutDialog(),
);
if (shouldLogout == true) {
await _handleLogout(context);
}
},
),
const SizedBox(height: 24),
],
),
],
),
);
} }
} }

View File

@@ -62,7 +62,8 @@ class _ATMLocatorScreenState extends State<ATMLocatorScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(AppLocalizations.of(context).atmlocator), // Title for the app bar title: Text(
AppLocalizations.of(context).atmlocator), // Title for the app bar
), ),
body: Stack( body: Stack(
children: [ children: [

View File

@@ -50,7 +50,7 @@ class _FaqsScreenState extends State<FaqsScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(AppLocalizations.of(context).faq), title: Text(AppLocalizations.of(context).faq),
), ),
body: Stack( body: Stack(
children: [ children: [