Welcome Screen for both Login and Mpin Page
This commit is contained in:
122
lib/app.dart
122
lib/app.dart
@@ -299,6 +299,126 @@ class _AuthGateState extends State<AuthGate> {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_checking) {
|
||||||
|
return const SplashScreen();
|
||||||
|
}
|
||||||
|
// ✅ Step 1: Show welcome screen first, only once
|
||||||
|
if (_showWelcome) {
|
||||||
|
return WelcomeScreen(
|
||||||
|
onContinue: () {
|
||||||
|
setState(() {
|
||||||
|
_showWelcome = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Step 2: Check login status
|
||||||
|
if (_isLoggedIn) {
|
||||||
|
if (_hasMPin) {
|
||||||
|
if (_biometricEnabled) {
|
||||||
|
return FutureBuilder<bool>(
|
||||||
|
future: _tryBiometric(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const SplashScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapshot.data == true) {
|
||||||
|
return const NavigationScaffold(); // Authenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ Biometric failed → Show MPIN screen
|
||||||
|
return MPinScreen(
|
||||||
|
mode: MPinMode.enter,
|
||||||
|
onCompleted: (_) {
|
||||||
|
Navigator.of(context).pushReplacement(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => const NavigationScaffold(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return MPinScreen(
|
||||||
|
mode: MPinMode.enter,
|
||||||
|
onCompleted: (_) {
|
||||||
|
Navigator.of(context).pushReplacement(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => const NavigationScaffold(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No MPIN set → show MPIN set screen + biometric dialog
|
||||||
|
return MPinScreen(
|
||||||
|
mode: MPinMode.set,
|
||||||
|
onCompleted: (_) async {
|
||||||
|
final storage = getIt<SecureStorage>();
|
||||||
|
final localAuth = LocalAuthentication();
|
||||||
|
|
||||||
|
final optIn = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (ctx) => AlertDialog(
|
||||||
|
title:
|
||||||
|
Text(AppLocalizations.of(context).enableFingerprintLogin),
|
||||||
|
content:
|
||||||
|
Text(AppLocalizations.of(context).enableFingerprintMessage),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(ctx).pop(false),
|
||||||
|
child: Text(AppLocalizations.of(context).no),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(ctx).pop(true),
|
||||||
|
child: Text(AppLocalizations.of(context).yes),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (optIn == true) {
|
||||||
|
final canCheck = await localAuth.canCheckBiometrics;
|
||||||
|
bool didAuth = false;
|
||||||
|
|
||||||
|
if (canCheck) {
|
||||||
|
didAuth = await localAuth.authenticate(
|
||||||
|
localizedReason:
|
||||||
|
AppLocalizations.of(context).authenticateToEnable,
|
||||||
|
options: const AuthenticationOptions(
|
||||||
|
stickyAuth: true,
|
||||||
|
biometricOnly: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await storage.write(
|
||||||
|
'biometric_enabled', didAuth ? 'true' : 'false');
|
||||||
|
} else {
|
||||||
|
await storage.write('biometric_enabled', 'false');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context).pushReplacement(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => const NavigationScaffold(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Step 3: If not logged in, show login screen
|
||||||
|
return const LoginScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_checking) {
|
if (_checking) {
|
||||||
return const SplashScreen();
|
return const SplashScreen();
|
||||||
@@ -416,7 +536,7 @@ class _AuthGateState extends State<AuthGate> {
|
|||||||
}
|
}
|
||||||
return const LoginScreen();
|
return const LoginScreen();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
class NavigationScaffold extends StatefulWidget {
|
class NavigationScaffold extends StatefulWidget {
|
||||||
const NavigationScaffold({super.key});
|
const NavigationScaffold({super.key});
|
||||||
|
@@ -43,18 +43,18 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context).kconnect,
|
AppLocalizations.of(context).kconnect,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 36,
|
fontSize: 36,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
letterSpacing: 1.5,
|
letterSpacing: 1.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context).kccBankFull,
|
AppLocalizations.of(context).kccBankFull,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
letterSpacing: 1.2,
|
letterSpacing: 1.2,
|
||||||
|
@@ -435,7 +435,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
const FundTransferBeneficiaryScreen()));
|
const FundTransferBeneficiaryScreen()));
|
||||||
}, disable: false),
|
}, disable: true),
|
||||||
_buildQuickLink(Symbols.server_person,
|
_buildQuickLink(Symbols.server_person,
|
||||||
AppLocalizations.of(context).accountInfo, () {
|
AppLocalizations.of(context).accountInfo, () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -457,7 +457,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
}),
|
}),
|
||||||
_buildQuickLink(Symbols.checkbook,
|
_buildQuickLink(Symbols.checkbook,
|
||||||
AppLocalizations.of(context).handleCheque, () {},
|
AppLocalizations.of(context).handleCheque, () {},
|
||||||
disable: false),
|
disable: true),
|
||||||
_buildQuickLink(Icons.group,
|
_buildQuickLink(Icons.group,
|
||||||
AppLocalizations.of(context).manageBeneficiary, () {
|
AppLocalizations.of(context).manageBeneficiary, () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -465,7 +465,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
const ManageBeneficiariesScreen()));
|
const ManageBeneficiariesScreen()));
|
||||||
}, disable: false),
|
}, disable: true),
|
||||||
_buildQuickLink(Symbols.support_agent,
|
_buildQuickLink(Symbols.support_agent,
|
||||||
AppLocalizations.of(context).contactUs, () {
|
AppLocalizations.of(context).contactUs, () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
Reference in New Issue
Block a user