APK Build #1
This commit is contained in:
BIN
assets/images/profile.png
Normal file
BIN
assets/images/profile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -12,10 +12,8 @@ import 'package:kmobile/features/auth/controllers/theme_state.dart';
|
|||||||
import 'config/routes.dart';
|
import 'config/routes.dart';
|
||||||
import 'di/injection.dart';
|
import 'di/injection.dart';
|
||||||
import 'features/auth/controllers/auth_cubit.dart';
|
import 'features/auth/controllers/auth_cubit.dart';
|
||||||
import 'features/card/screens/card_management_screen.dart';
|
|
||||||
import 'features/accounts/screens/account_statement_screen.dart';
|
import 'features/accounts/screens/account_statement_screen.dart';
|
||||||
import 'package:kmobile/features/auth/controllers/auth_state.dart';
|
import 'package:kmobile/features/auth/controllers/auth_state.dart';
|
||||||
|
|
||||||
import 'features/auth/screens/login_screen.dart';
|
import 'features/auth/screens/login_screen.dart';
|
||||||
import 'features/service/screens/service_screen.dart';
|
import 'features/service/screens/service_screen.dart';
|
||||||
import 'features/dashboard/screens/dashboard_screen.dart';
|
import 'features/dashboard/screens/dashboard_screen.dart';
|
||||||
@@ -330,7 +328,6 @@ class _NavigationScaffoldState extends State<NavigationScaffold> {
|
|||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const CardManagementScreen(),
|
|
||||||
const ServiceScreen(),
|
const ServiceScreen(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -392,10 +389,6 @@ class _NavigationScaffoldState extends State<NavigationScaffold> {
|
|||||||
icon: const Icon(Icons.swap_vert_sharp),
|
icon: const Icon(Icons.swap_vert_sharp),
|
||||||
label: AppLocalizations.of(context).transactions,
|
label: AppLocalizations.of(context).transactions,
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: const Icon(Icons.credit_card),
|
|
||||||
label: AppLocalizations.of(context).card,
|
|
||||||
),
|
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: const Icon(Icons.miscellaneous_services),
|
icon: const Icon(Icons.miscellaneous_services),
|
||||||
label: AppLocalizations.of(context).services,
|
label: AppLocalizations.of(context).services,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class _AccountInfoScreen extends State<AccountInfoScreen> {
|
|||||||
return AppLocalizations.of(context).recurringDeposit;
|
return AppLocalizations.of(context).recurringDeposit;
|
||||||
case 'ca':
|
case 'ca':
|
||||||
return "Current Account";
|
return "Current Account";
|
||||||
case 'cc':
|
case 'cc':
|
||||||
return "Cash Credit Account";
|
return "Cash Credit Account";
|
||||||
case 'od':
|
case 'od':
|
||||||
return "Overdraft Account";
|
return "Overdraft Account";
|
||||||
|
|||||||
@@ -150,36 +150,42 @@ class _AccountStatementScreen extends State<AccountStatementScreen> {
|
|||||||
margin: const EdgeInsets.only(bottom: 10),
|
margin: const EdgeInsets.only(bottom: 10),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context).accountNumber,
|
AppLocalizations.of(context).accountNumber,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w500, fontSize: 17),
|
fontWeight: FontWeight.w500, fontSize: 17),
|
||||||
),
|
),
|
||||||
const VerticalDivider(width: 20, thickness: 1, indent: 5, endIndent: 5, color: Colors.grey),
|
const VerticalDivider(
|
||||||
DropdownButton<User>(
|
width: 20,
|
||||||
value: selectedUser,
|
thickness: 1,
|
||||||
onChanged: (User? newUser) {
|
indent: 5,
|
||||||
if (newUser != null) {
|
endIndent: 5,
|
||||||
setState(() {
|
color: Colors.grey),
|
||||||
selectedUser = newUser;
|
DropdownButton<User>(
|
||||||
});
|
value: selectedUser,
|
||||||
_loadTransactions();
|
onChanged: (User? newUser) {
|
||||||
}
|
if (newUser != null) {
|
||||||
},
|
setState(() {
|
||||||
items: widget.users.map((user) {
|
selectedUser = newUser;
|
||||||
return DropdownMenuItem<User>(
|
});
|
||||||
value: user,
|
_loadTransactions();
|
||||||
child: Text(user.accountNo.toString()),
|
}
|
||||||
);
|
},
|
||||||
}).toList(),
|
items: widget.users.map((user) {
|
||||||
underline: Container(), // Remove the underline
|
return DropdownMenuItem<User>(
|
||||||
),
|
value: user,
|
||||||
Spacer(),
|
child: Text(user.accountNo.toString()),
|
||||||
],
|
);
|
||||||
), ),
|
}).toList(),
|
||||||
|
underline: Container(), // Remove the underline
|
||||||
|
),
|
||||||
|
Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Card(
|
Card(
|
||||||
margin: const EdgeInsets.only(bottom: 10),
|
margin: const EdgeInsets.only(bottom: 10),
|
||||||
|
|||||||
@@ -26,149 +26,152 @@ class _CustomerInfoScreenState extends State<CustomerInfoScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context)
|
AppLocalizations.of(context)
|
||||||
.customerInfo
|
.customerInfo
|
||||||
.replaceFirst(RegExp('\n'), ''),
|
.replaceFirst(RegExp('\n'), ''),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
body: SafeArea(
|
||||||
body: SafeArea(
|
child: Stack(
|
||||||
child: Stack(
|
children: [
|
||||||
children: [
|
SingleChildScrollView(
|
||||||
SingleChildScrollView(
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(16.0),
|
||||||
padding: const EdgeInsets.all(16.0),
|
child: Column(
|
||||||
child: Column(
|
children: [
|
||||||
children: [
|
Card(
|
||||||
Card(
|
elevation: 0,
|
||||||
elevation: 0,
|
shape: RoundedRectangleBorder(
|
||||||
shape: RoundedRectangleBorder(
|
borderRadius: BorderRadius.circular(12),
|
||||||
borderRadius: BorderRadius.circular(12),
|
side: BorderSide(
|
||||||
side: BorderSide(
|
color: theme.colorScheme.outline.withOpacity(0.2),
|
||||||
color: theme.colorScheme.outline.withOpacity(0.2),
|
width: 1,
|
||||||
width: 1,
|
),
|
||||||
),
|
),
|
||||||
),
|
child: Padding(
|
||||||
child: Padding( padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 56,
|
width: 56,
|
||||||
height: 56,
|
height: 56,
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
radius: 50,
|
radius: 50,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
'assets/images/avatar_male.svg',
|
'assets/images/avatar_male.svg',
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 12),
|
||||||
const SizedBox(width: 12),
|
// Name + mobile
|
||||||
// Name + mobile
|
Expanded(
|
||||||
Expanded(
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
// If you want to show the user's name instead, replace below.
|
||||||
// If you want to show the user's name instead, replace below.
|
user.name ?? '',
|
||||||
user.name ?? '',
|
style:
|
||||||
style:
|
theme.textTheme.titleLarge?.copyWith(
|
||||||
theme.textTheme.titleLarge?.copyWith(
|
fontWeight: FontWeight.w600,
|
||||||
fontWeight: FontWeight.w600,
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 4),
|
||||||
const SizedBox(height: 4),
|
Text(
|
||||||
Text(
|
user.cifNumber ?? '',
|
||||||
user.cifNumber ?? '',
|
style:
|
||||||
style: theme.textTheme.bodyMedium?.copyWith(
|
theme.textTheme.bodyMedium?.copyWith(
|
||||||
color: theme.colorScheme.onSurface
|
color: theme.colorScheme.onSurface
|
||||||
.withOpacity(0.7),
|
.withOpacity(0.7),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 16),
|
||||||
const SizedBox(height: 16),
|
Card(
|
||||||
Card(
|
elevation: 0,
|
||||||
elevation: 0,
|
shape: RoundedRectangleBorder(
|
||||||
shape: RoundedRectangleBorder(
|
borderRadius: BorderRadius.circular(12),
|
||||||
borderRadius: BorderRadius.circular(12),
|
side: BorderSide(
|
||||||
side: BorderSide(
|
color: theme.colorScheme.outline.withOpacity(0.2),
|
||||||
color: theme.colorScheme.outline.withOpacity(0.2),
|
width: 1,
|
||||||
width: 1,
|
),
|
||||||
),
|
),
|
||||||
),
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(16.0),
|
||||||
padding: const EdgeInsets.all(16.0),
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
'Personal Information',
|
||||||
'Personal Information',
|
style: theme.textTheme.titleMedium?.copyWith(
|
||||||
style: theme.textTheme.titleMedium?.copyWith(
|
fontWeight: FontWeight.w600,
|
||||||
fontWeight: FontWeight.w600,
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 16),
|
||||||
const SizedBox(height: 16),
|
InfoField(
|
||||||
InfoField(
|
label:
|
||||||
label: AppLocalizations.of(context).activeAccounts,
|
AppLocalizations.of(context).activeAccounts,
|
||||||
value: user.activeAccounts?.toString() ?? 'N/A',
|
value: user.activeAccounts?.toString() ?? 'N/A',
|
||||||
),
|
),
|
||||||
InfoField(
|
InfoField(
|
||||||
label: AppLocalizations.of(context).mobileNumber,
|
label:
|
||||||
value: user.mobileNo ?? 'N/A',
|
AppLocalizations.of(context).mobileNumber,
|
||||||
),
|
value: user.mobileNo ?? 'N/A',
|
||||||
InfoField(
|
),
|
||||||
label: AppLocalizations.of(context).dateOfBirth,
|
InfoField(
|
||||||
value: (user.dateOfBirth != null &&
|
label: AppLocalizations.of(context).dateOfBirth,
|
||||||
user.dateOfBirth!.length == 8)
|
value: (user.dateOfBirth != null &&
|
||||||
? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}'
|
user.dateOfBirth!.length == 8)
|
||||||
: 'N/A',
|
? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}'
|
||||||
), // Replace with DOB if available
|
: 'N/A',
|
||||||
InfoField(
|
), // Replace with DOB if available
|
||||||
label: AppLocalizations.of(context).branchCode,
|
InfoField(
|
||||||
value: user.branchId ?? 'N/A',
|
label: AppLocalizations.of(context).branchCode,
|
||||||
),
|
value: user.branchId ?? 'N/A',
|
||||||
InfoField(
|
),
|
||||||
label: AppLocalizations.of(context).address,
|
InfoField(
|
||||||
value: user.address ?? 'N/A',
|
label: AppLocalizations.of(context).address,
|
||||||
), // Replace with Aadhar if available
|
value: user.address ?? 'N/A',
|
||||||
InfoField(
|
), // Replace with Aadhar if available
|
||||||
label: AppLocalizations.of(context).primaryId,
|
InfoField(
|
||||||
value: _maskPrimaryId(user.primaryId),
|
label: AppLocalizations.of(context).primaryId,
|
||||||
),
|
value: _maskPrimaryId(user.primaryId),
|
||||||
],
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
IgnorePointer(
|
||||||
IgnorePointer(
|
child: Center(
|
||||||
child: Center(
|
child: Opacity(
|
||||||
child: Opacity(
|
opacity: 0.07, // Reduced opacity
|
||||||
opacity: 0.07, // Reduced opacity
|
child: ClipOval(
|
||||||
child: ClipOval(
|
child: Image.asset(
|
||||||
child: Image.asset(
|
'assets/images/logo.png',
|
||||||
'assets/images/logo.png',
|
width: 200, // Adjust size as needed
|
||||||
width: 200, // Adjust size as needed
|
height: 200, // Adjust size as needed
|
||||||
height: 200, // Adjust size as needed
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,260 +174,240 @@ 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: CircleAvatar(
|
|
||||||
radius: 50,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
'assets/images/avatar_male.svg',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
// Name + mobile
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
// Avatar
|
||||||
// If you want to show the user's name instead, replace below.
|
Container(
|
||||||
widget.customerName,
|
width: 56,
|
||||||
style: theme.textTheme.titleLarge?.copyWith(
|
height: 56,
|
||||||
fontWeight: FontWeight.w600,
|
child: CircleAvatar(
|
||||||
|
radius: 50,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
'assets/images/avatar_male.svg',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(width: 12),
|
||||||
Text(
|
// Name + mobile
|
||||||
widget.customerNo,
|
Expanded(
|
||||||
style: theme.textTheme.bodyMedium?.copyWith(
|
child: Column(
|
||||||
color: theme.colorScheme.onSurface
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
.withOpacity(0.7),
|
children: [
|
||||||
|
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(),
|
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
const SizedBox(height: 16),
|
||||||
),
|
|
||||||
_SectionTile(
|
// ===== Section: Settings =====
|
||||||
leadingIcon: Icons.security,
|
Padding(
|
||||||
title: loc.securitySettings,
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
onTap: () {
|
child: Text(
|
||||||
Navigator.push(
|
"Settings",
|
||||||
context,
|
style: theme.textTheme.labelLarge?.copyWith(
|
||||||
MaterialPageRoute(
|
fontWeight: FontWeight.w600,
|
||||||
builder: (context) => SecuritySettingsScreen(
|
letterSpacing: 0.2,
|
||||||
mobileNumber: widget.mobileNumber,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
const SizedBox(height: 8),
|
||||||
},
|
|
||||||
),
|
|
||||||
_SectionTile(
|
|
||||||
leadingIcon: Icons.currency_rupee,
|
|
||||||
title: loc.dailylimit,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => const DailyLimitScreen(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
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),
|
_SectionTile(
|
||||||
const Divider(height: 24),
|
leadingIcon: Icons.settings,
|
||||||
|
title: loc.preferences,
|
||||||
// ===== Section: Security & App =====
|
onTap: () {
|
||||||
Padding(
|
Navigator.push(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
context,
|
||||||
child: Text(
|
MaterialPageRoute(
|
||||||
loc.appVersion,
|
builder: (context) => const PreferenceScreen(),
|
||||||
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 {
|
_SectionTile(
|
||||||
return Text(
|
leadingIcon: Icons.security,
|
||||||
snapshot.data ?? "N/A",
|
title: loc.securitySettings,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => SecuritySettingsScreen(
|
||||||
|
mobileNumber: widget.mobileNumber,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
|
||||||
),
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
_SectionTile(
|
||||||
|
leadingIcon: Icons.currency_rupee,
|
||||||
if (shouldExit == true) {
|
title: loc.dailylimit,
|
||||||
if (Platform.isAndroid) {
|
onTap: () {
|
||||||
SystemNavigator.pop();
|
Navigator.push(
|
||||||
}
|
context,
|
||||||
exit(0);
|
MaterialPageRoute(
|
||||||
}
|
builder: (context) => const DailyLimitScreen(),
|
||||||
},
|
),
|
||||||
),
|
);
|
||||||
_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),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
// ===== Watermark (kept subtle, no theme change) =====
|
|
||||||
IgnorePointer(
|
|
||||||
child: Positioned.fill(
|
|
||||||
child: Center(
|
|
||||||
child: Opacity(
|
|
||||||
opacity: 0.06,
|
|
||||||
child: ClipOval(
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/logo.png',
|
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
filterQuality: FilterQuality.medium,
|
|
||||||
),
|
),
|
||||||
),
|
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),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
), );
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ void main() async {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Check for device compromise
|
// Check for device compromise
|
||||||
//final compromisedMessage = await SecurityService.deviceCompromisedMessage;
|
// final compromisedMessage = await SecurityService.deviceCompromisedMessage;
|
||||||
// if (compromisedMessage != null) {
|
// if (compromisedMessage != null) {
|
||||||
// runApp(MaterialApp(
|
// runApp(MaterialApp(
|
||||||
// home: SecurityErrorScreen(message: compromisedMessage),
|
// home: SecurityErrorScreen(message: compromisedMessage),
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ flutter:
|
|||||||
- assets/images/uco_logo.png
|
- assets/images/uco_logo.png
|
||||||
- assets/images/ipos_logo.png
|
- assets/images/ipos_logo.png
|
||||||
- assets/images/profile.svg
|
- assets/images/profile.svg
|
||||||
|
- assets/images/profile.png
|
||||||
- assets/animations/rupee.json
|
- assets/animations/rupee.json
|
||||||
- assets/animations/error.json
|
- assets/animations/error.json
|
||||||
- assets/animations/done.json
|
- assets/animations/done.json
|
||||||
|
|||||||
Reference in New Issue
Block a user