Language Change

This commit is contained in:
Nilanjan Chakrabarti
2025-07-10 13:19:31 +05:30
parent 9b439338a9
commit d4de89a91f
22 changed files with 334 additions and 227 deletions

View File

@@ -14,7 +14,7 @@ import 'features/auth/screens/welcome_screen.dart';
import 'features/auth/screens/login_screen.dart';
import 'features/service/screens/service_screen.dart';
import 'features/dashboard/screens/dashboard_screen.dart';
//import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'features/auth/screens/mpin_screen.dart';
import 'package:local_auth/local_auth.dart';
@@ -186,7 +186,7 @@ class _AuthGateState extends State<AuthGate> {
if (!canCheck) return false;
try {
final didAuth = await localAuth.authenticate(
localizedReason: 'Authenticate to access kMobile',
localizedReason: AppLocalizations.of(context).authenticateToAccess,
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
@@ -353,18 +353,19 @@ class _AuthGateState extends State<AuthGate> {
context: context,
barrierDismissible: false,
builder: (ctx) => AlertDialog(
title: const Text('Enable Fingerprint Login?'),
content: const Text(
'Would you like to enable fingerprint authentication for faster login?',
title:
Text(AppLocalizations.of(context).enableFingerprintLogin),
content: Text(
AppLocalizations.of(context).enableFingerprintMessage,
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(false),
child: const Text('No'),
child: Text(AppLocalizations.of(context).no),
),
TextButton(
onPressed: () => Navigator.of(ctx).pop(true),
child: const Text('Yes'),
child: Text(AppLocalizations.of(context).yes),
),
],
),
@@ -376,7 +377,8 @@ class _AuthGateState extends State<AuthGate> {
if (canCheck) {
didAuth = await localAuth.authenticate(
localizedReason: 'Authenticate to enable fingerprint login.',
localizedReason:
AppLocalizations.of(context).authenticateToEnable,
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
@@ -449,16 +451,16 @@ class _NavigationScaffoldState extends State<NavigationScaffold> {
final shouldExit = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Exit App'),
content: const Text('Do you really want to exit?'),
title: Text(AppLocalizations.of(context).exitApp),
content: Text(AppLocalizations.of(context).exitConfirmation),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text('No'),
child: Text(AppLocalizations.of(context).no),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text('Yes'),
child: Text(AppLocalizations.of(context).yes),
),
],
),
@@ -515,7 +517,7 @@ class SplashScreen extends StatelessWidget {
children: [
const CircularProgressIndicator(),
const SizedBox(height: 20),
Text('Loading...',
Text(AppLocalizations.of(context).loading,
style: Theme.of(context).textTheme.headlineMedium),
],
),
@@ -537,7 +539,7 @@ class BiometricPromptScreen extends StatelessWidget {
return;
}
final didAuth = await localAuth.authenticate(
localizedReason: 'Enable fingerprint authentication for quick login?',
localizedReason: AppLocalizations.of(context).enableFingerprintQuick,
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
@@ -563,21 +565,20 @@ class BiometricPromptScreen extends StatelessWidget {
context: context,
barrierDismissible: true,
builder: (ctx) => AlertDialog(
title: const Text('Enable Fingerprint Login?'),
content: const Text(
'Would you like to enable fingerprint authentication for faster login?'),
title: Text(AppLocalizations.of(context).enableFingerprintLogin),
content: Text(AppLocalizations.of(context).enableFingerprintMessage),
actions: [
TextButton(
onPressed: () {
Navigator.of(ctx).pop(false);
},
child: const Text('No'),
child: Text(AppLocalizations.of(context).no),
),
TextButton(
onPressed: () {
Navigator.of(ctx).pop(true);
},
child: const Text('Yes'),
child: Text(AppLocalizations.of(context).yes),
),
],
),

View File

@@ -44,7 +44,9 @@ class _AccountStatementScreen extends State<AccountStatementScreen> {
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to load transactions: $e')),
SnackBar(
content: Text(
'${AppLocalizations.of(context).failedToLoadTransactions} $e')),
);
} finally {
setState(() => _txLoading = false);
@@ -70,7 +72,8 @@ class _AccountStatementScreen extends State<AccountStatementScreen> {
Future<void> _selectToDate(BuildContext context) async {
if (fromDate == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Please select From Date first')),
SnackBar(
content: Text(AppLocalizations.of(context).pleaseSelectDateFirst)),
);
return;
}

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kmobile/di/injection.dart';
@@ -110,8 +112,8 @@ class LoginScreenState extends State<LoginScreen>
),
const SizedBox(height: 16),
// Title
const Text(
'KCCB',
Text(
AppLocalizations.of(context).kccb,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
@@ -121,8 +123,8 @@ class LoginScreenState extends State<LoginScreen>
TextFormField(
controller: _customerNumberController,
decoration: const InputDecoration(
labelText: 'Customer Number',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).customerNumber,
// prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
isDense: true,
@@ -139,7 +141,7 @@ class LoginScreenState extends State<LoginScreen>
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your username';
return AppLocalizations.of(context).pleaseEnterUsername;
}
return null;
},
@@ -153,7 +155,7 @@ class LoginScreenState extends State<LoginScreen>
onFieldSubmitted: (_) =>
_submitForm(), // ⌨️ Enter key submits
decoration: InputDecoration(
labelText: 'Password',
labelText: AppLocalizations.of(context).password,
border: const OutlineInputBorder(),
isDense: true,
filled: true,
@@ -179,7 +181,7 @@ class LoginScreenState extends State<LoginScreen>
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
return AppLocalizations.of(context).pleaseEnterPassword;
}
return null;
},
@@ -200,22 +202,22 @@ class LoginScreenState extends State<LoginScreen>
),
child: state is AuthLoading
? const CircularProgressIndicator()
: const Text(
"Login",
: Text(
AppLocalizations.of(context).login,
style: TextStyle(fontSize: 16),
),
),
),
const SizedBox(height: 15),
const Padding(
Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Row(
children: [
Expanded(child: Divider()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Text('OR'),
child: Text(AppLocalizations.of(context).or),
),
Expanded(child: Divider()),
],
@@ -235,7 +237,7 @@ class LoginScreenState extends State<LoginScreen>
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: Colors.lightBlue[100],
foregroundColor: Colors.black),
child: const Text('Register'),
child: Text(AppLocalizations.of(context).register),
),
),
],
@@ -471,4 +473,4 @@ class LoginScreenState extends State<LoginScreen> {
);
}
}
*/
*/

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'dart:developer';
import 'package:flutter/material.dart';
@@ -44,7 +46,7 @@ class _MPinScreenState extends State<MPinScreen> {
final auth = LocalAuthentication();
if (await auth.canCheckBiometrics) {
final didAuth = await auth.authenticate(
localizedReason: 'Authenticate to access kMobile',
localizedReason: AppLocalizations.of(context).authenticateToAccess,
options: const AuthenticationOptions(biometricOnly: true),
);
if (didAuth && mounted) {
@@ -91,7 +93,7 @@ class _MPinScreenState extends State<MPinScreen> {
widget.onCompleted?.call(pin);
} else {
setState(() {
errorText = "Incorrect mPIN. Try again.";
errorText = AppLocalizations.of(context).incorrectMPIN;
mPin.clear();
});
}
@@ -123,7 +125,7 @@ class _MPinScreenState extends State<MPinScreen> {
}
} else {
setState(() {
errorText = "Pins do not match. Try again.";
errorText = AppLocalizations.of(context).pinsDoNotMatch;
mPin.clear();
});
}
@@ -172,7 +174,8 @@ class _MPinScreenState extends State<MPinScreen> {
_handleComplete();
} else {
setState(() {
errorText = "Please enter 4 digits";
errorText =
AppLocalizations.of(context).pleaseEnter4Digits;
});
}
} else if (key.isNotEmpty) {
@@ -208,11 +211,11 @@ class _MPinScreenState extends State<MPinScreen> {
String getTitle() {
switch (widget.mode) {
case MPinMode.enter:
return "Enter your mPIN";
return AppLocalizations.of(context).enterMPIN;
case MPinMode.set:
return "Set your new mPIN";
return AppLocalizations.of(context).setMPIN;
case MPinMode.confirm:
return "Confirm your mPIN";
return AppLocalizations.of(context).confirmMPIN;
}
}

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'dart:async';
@@ -38,9 +40,9 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
children: [
Text(
'Kconnect',
AppLocalizations.of(context).kconnect,
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.bold,
@@ -50,7 +52,7 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
),
SizedBox(height: 12),
Text(
'Kangra Central Co-operative Bank',
AppLocalizations.of(context).kccBankFull,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,

View File

@@ -36,7 +36,7 @@ class _BlockCardScreen extends State<BlockCardScreen> {
// Call your backend logic here
final snackBar = SnackBar(
content: const Text('Card has been blocked'),
content: Text(AppLocalizations.of(context).cardBlocked),
action: SnackBarAction(
label: 'X',
onPressed: () {
@@ -62,8 +62,8 @@ class _BlockCardScreen extends State<BlockCardScreen> {
Navigator.pop(context);
},
),
title: const Text(
'Block Card',
title: Text(
AppLocalizations.of(context).blockCard,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
@@ -109,7 +109,7 @@ class _BlockCardScreen extends State<BlockCardScreen> {
textInputAction: TextInputAction.next,
validator: (value) => value != null && value.length == 11
? null
: 'Enter valid card number',
: AppLocalizations.of(context).enterValidCardNumber,
),
const SizedBox(height: 24),
Row(
@@ -135,7 +135,7 @@ class _BlockCardScreen extends State<BlockCardScreen> {
obscureText: true,
validator: (value) => value != null && value.length == 3
? null
: 'CVV must be 3 digits',
: AppLocalizations.of(context).cvv3Digits,
),
),
const SizedBox(width: 16),
@@ -160,7 +160,7 @@ class _BlockCardScreen extends State<BlockCardScreen> {
),
validator: (value) => value != null && value.isNotEmpty
? null
: 'Select expiry date',
: AppLocalizations.of(context).selectExpiryDate,
),
),
],

View File

@@ -18,8 +18,8 @@ class _CardManagementScreen extends State<CardManagementScreen> {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text(
'Card Management',
title: Text(
AppLocalizations.of(context).cardManagement,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,

View File

@@ -52,8 +52,8 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
Navigator.pop(context);
},
),
title: const Text(
'Card Details',
title: Text(
AppLocalizations.of(context).cardDetails,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
@@ -99,7 +99,7 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
textInputAction: TextInputAction.next,
validator: (value) => value != null && value.length == 11
? null
: 'Enter valid card number',
: AppLocalizations.of(context).enterValidCardNumber,
),
const SizedBox(height: 24),
Row(
@@ -125,7 +125,7 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
obscureText: true,
validator: (value) => value != null && value.length == 3
? null
: 'CVV must be 3 digits',
: AppLocalizations.of(context).cvv3Digits,
),
),
const SizedBox(width: 16),
@@ -150,7 +150,7 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
),
validator: (value) => value != null && value.isNotEmpty
? null
: 'Select expiry date',
: AppLocalizations.of(context).selectExpiryDate,
),
),
],
@@ -176,7 +176,7 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
keyboardType: TextInputType.phone,
validator: (value) => value != null && value.length >= 10
? null
: 'Enter valid phone number',
: AppLocalizations.of(context).enterValidPhone,
),
const SizedBox(height: 45),
Align(

View File

@@ -19,7 +19,7 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
if (_formKey.currentState!.validate()) {
// Handle PIN submission logic here
final snackBar = SnackBar(
content: const Text('PIN set successfully'),
content: Text(AppLocalizations.of(context).pinSetSuccess),
action: SnackBarAction(
label: 'X',
onPressed: () {
@@ -52,8 +52,8 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
Navigator.pop(context);
},
),
title: const Text(
'Card PIN',
title: Text(
AppLocalizations.of(context).cardPin,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
@@ -82,8 +82,8 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
TextFormField(
controller: _pinController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Enter new PIN',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).enterNewPin,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -99,10 +99,10 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter new PIN';
return AppLocalizations.of(context).pleaseEnterNewPin;
}
if (value.length < 4) {
return 'PIN must be at least 4 digits';
return AppLocalizations.of(context).pin4Digits;
}
return null;
},
@@ -111,8 +111,8 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
TextFormField(
controller: _confirmPinController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Enter Again',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).enterAgain,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -128,7 +128,7 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
textInputAction: TextInputAction.done,
validator: (value) {
if (value != _pinController.text) {
return 'PINs do not match';
return AppLocalizations.of(context).pinsDoNotMatch;
}
return null;
},
@@ -146,7 +146,7 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
backgroundColor: Colors.blue[900],
foregroundColor: Colors.white,
),
child: const Text('Submit'),
child: Text(AppLocalizations.of(context).submit),
),
),
),

View File

@@ -22,8 +22,8 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
Navigator.pop(context);
},
),
title: const Text(
'Cheque Management',
title: Text(
AppLocalizations.of(context).chequeManagement,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
@@ -48,7 +48,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
const SizedBox(height: 15),
ChequeManagementTile(
icon: Symbols.add,
label: 'Request Checkbook',
label: AppLocalizations.of(context).requestChequeBook,
onTap: () {},
),
const Divider(
@@ -56,7 +56,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
),
ChequeManagementTile(
icon: Symbols.data_alert,
label: 'Enquiry',
label: AppLocalizations.of(context).enquiry,
onTap: () {
Navigator.push(
context,
@@ -69,7 +69,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
),
ChequeManagementTile(
icon: Symbols.approval_delegation,
label: 'Cheque Deposit',
label: AppLocalizations.of(context).chequeDeposit,
onTap: () {},
),
const Divider(
@@ -77,7 +77,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
),
ChequeManagementTile(
icon: Symbols.front_hand,
label: 'Stop Cheque',
label: AppLocalizations.of(context).stopCheque,
onTap: () {},
),
const Divider(
@@ -85,7 +85,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
),
ChequeManagementTile(
icon: Symbols.cancel_presentation,
label: 'Revoke Stop',
label: AppLocalizations.of(context).revokeStop,
onTap: () {},
),
const Divider(
@@ -93,7 +93,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
),
ChequeManagementTile(
icon: Symbols.payments,
label: 'Positive Pay',
label: AppLocalizations.of(context).positivePay,
onTap: () {},
),
const Divider(

View File

@@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import '../../accounts/models/account.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class AccountCard extends StatelessWidget {
final Account account;
const AccountCard({
super.key,
required this.account,
@@ -48,8 +49,8 @@ class AccountCard extends StatelessWidget {
),
),
Icon(
account.accountType == 'Savings'
? Icons.savings
account.accountType == 'Savings'
? Icons.savings
: Icons.account_balance,
color: Colors.white,
),
@@ -73,8 +74,8 @@ class AccountCard extends StatelessWidget {
),
),
const SizedBox(height: 5),
const Text(
'Available Balance',
Text(
AppLocalizations.of(context).availableBalance,
style: TextStyle(
color: Colors.white70,
fontSize: 12,
@@ -84,4 +85,4 @@ class AccountCard extends StatelessWidget {
),
);
}
}
}

View File

@@ -22,7 +22,7 @@ class _FundTransferScreen extends State<FundTransferScreen> {
}
} else if (key == 'done') {
if (kDebugMode) {
print('Amount entered: $amount');
print('${AppLocalizations.of(context).amountEntered} $amount');
// Navigator.push(
// context,
// MaterialPageRoute(

View File

@@ -7,6 +7,7 @@ import 'package:kmobile/data/models/payment_response.dart';
import 'package:lottie/lottie.dart';
import 'package:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class PaymentAnimationScreen extends StatefulWidget {
final Future<PaymentResponse> paymentResponse;
@@ -36,11 +37,14 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
final file = await File('${tempDir.path}/payment_result.png').create();
await file.writeAsBytes(pngBytes);
await Share.shareXFiles([XFile(file.path)], text: 'Payment Result');
await Share.shareXFiles([XFile(file.path)],
text: '${AppLocalizations.of(context).paymentResult}');
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to share screenshot: $e')),
SnackBar(
content: Text(
'${AppLocalizations.of(context).failedToShareScreenshot}: $e')),
);
}
}
@@ -88,8 +92,9 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
isSuccess
? Column(
children: [
const Text(
'Payment Successful!',
Text(
AppLocalizations.of(context)
.paymentSuccessful,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
@@ -98,7 +103,7 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
const SizedBox(height: 16),
if (response.amount != null)
Text(
'Amount: ${response.amount} ${response.currency ?? ''}',
'${AppLocalizations.of(context).amount}: ${response.amount} ${response.currency ?? ''}',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w700,
@@ -106,7 +111,7 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
),
if (response.creditedAccount != null)
Text(
'Credited Account: ${response.creditedAccount}',
'${AppLocalizations.of(context).creditedAccount}: ${response.creditedAccount}',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
@@ -121,8 +126,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
)
: Column(
children: [
const Text(
'Payment Failed',
Text(
AppLocalizations.of(context).paymentFailed,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
@@ -156,7 +161,7 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
Icons.share_rounded,
color: Theme.of(context).primaryColor,
),
label: Text('Share',
label: Text(AppLocalizations.of(context).share,
style:
TextStyle(color: Theme.of(context).primaryColor)),
style: ElevatedButton.styleFrom(
@@ -182,7 +187,7 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
Navigator.of(context)
.popUntil((route) => route.isFirst);
},
label: const Text('Done'),
label: Text(AppLocalizations.of(context).done),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 45, vertical: 12),

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:kmobile/features/fund_transfer/screens/tpin_set_screen.dart';
@@ -46,7 +48,7 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Invalid OTP')),
SnackBar(content: Text(AppLocalizations.of(context).invalidOtp)),
);
}
}
@@ -56,7 +58,7 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Enter OTP'),
title: Text(AppLocalizations.of(context).enterOtp),
centerTitle: true,
elevation: 0,
),
@@ -69,7 +71,7 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
size: 48, color: theme.colorScheme.primary),
const SizedBox(height: 16),
Text(
'OTP Verification',
AppLocalizations.of(context).otpVerification,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: theme.colorScheme.primary,
@@ -77,7 +79,7 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
),
const SizedBox(height: 8),
Text(
'Enter the 4-digit OTP sent to your mobile number.',
AppLocalizations.of(context).otpSentMessage,
textAlign: TextAlign.center,
style: theme.textTheme.bodyMedium?.copyWith(
color: Colors.grey[700],
@@ -125,8 +127,8 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
const SizedBox(height: 32),
ElevatedButton.icon(
icon: const Icon(Icons.verified_user_rounded),
label: const Text(
'Verify OTP',
label: Text(
AppLocalizations.of(context).verifyOtp,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
style: ElevatedButton.styleFrom(
@@ -144,10 +146,11 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
onPressed: () {
// Resend OTP logic here
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('OTP resent (mock)')),
SnackBar(
content: Text(AppLocalizations.of(context).otpResent)),
);
},
child: const Text('Resend OTP'),
child: Text(AppLocalizations.of(context).resendOtp),
),
const SizedBox(height: 60),
],

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:kmobile/features/fund_transfer/screens/tpin_otp_screen.dart';
@@ -9,7 +11,7 @@ class TpinSetupPromptScreen extends StatelessWidget {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Set TPIN'),
title: Text(AppLocalizations.of(context).setTpin),
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 100.0),
@@ -20,7 +22,7 @@ class TpinSetupPromptScreen extends StatelessWidget {
size: 60, color: theme.colorScheme.primary),
const SizedBox(height: 18),
Text(
'TPIN Required',
AppLocalizations.of(context).tpinRequired,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: theme.colorScheme.primary,
@@ -28,7 +30,7 @@ class TpinSetupPromptScreen extends StatelessWidget {
),
const SizedBox(height: 12),
Text(
'You need to set your TPIN to continue with secure transactions.',
AppLocalizations.of(context).tpinRequiredMessage,
textAlign: TextAlign.center,
style: theme.textTheme.bodyMedium?.copyWith(
color: Colors.grey[700],
@@ -37,8 +39,8 @@ class TpinSetupPromptScreen extends StatelessWidget {
const SizedBox(height: 32),
ElevatedButton.icon(
icon: const Icon(Icons.arrow_forward_rounded),
label: const Text(
'Set TPIN',
label: Text(
AppLocalizations.of(context).setTpin,
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
style: ElevatedButton.styleFrom(
@@ -62,7 +64,7 @@ class TpinSetupPromptScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18.0),
child: Text(
'Your TPIN is a 6-digit code used to authorize transactions. Keep it safe and do not share it with anyone.',
AppLocalizations.of(context).tpinInfo,
textAlign: TextAlign.center,
style: theme.textTheme.bodySmall?.copyWith(
color: Colors.grey[600],

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:kmobile/api/services/auth_service.dart';
import 'package:kmobile/di/injection.dart';
@@ -53,7 +55,7 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
await authService.setTpin(pin);
} catch (e) {
setState(() {
_errorText = "Failed to set TPIN. Please try again.";
_errorText = "${AppLocalizations.of(context).tpinFailed}";
_tpin.clear();
});
return;
@@ -66,15 +68,16 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
builder: (ctx) => AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)),
title: const Column(
title: Column(
children: [
Icon(Icons.check_circle, color: Colors.green, size: 60),
SizedBox(height: 12),
Text('Success!', style: TextStyle(fontWeight: FontWeight.bold)),
Text(AppLocalizations.of(context).success,
style: TextStyle(fontWeight: FontWeight.bold)),
],
),
content: const Text(
'Your TPIN was set up successfully.',
content: Text(
AppLocalizations.of(context).tpinSetSuccess,
textAlign: TextAlign.center,
),
actions: [
@@ -82,7 +85,8 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
onPressed: () {
Navigator.of(ctx).pop();
},
child: const Text('OK', style: TextStyle(fontSize: 16)),
child: Text(AppLocalizations.of(context).ok,
style: TextStyle(fontSize: 16)),
),
],
),
@@ -92,7 +96,7 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
}
} else {
setState(() {
_errorText = "Pins do not match. Try again.";
_errorText = AppLocalizations.of(context).pinsMismatchRetry;
_tpin.clear();
});
}
@@ -140,7 +144,8 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
_handleComplete();
} else {
setState(() {
_errorText = "Please enter 6 digits";
_errorText =
AppLocalizations.of(context).pleaseEnter6Digits;
});
}
} else if (key.isNotEmpty) {
@@ -176,16 +181,16 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
String getTitle() {
switch (_mode) {
case TPinMode.set:
return "Set your new TPIN";
return AppLocalizations.of(context).setNewTpin;
case TPinMode.confirm:
return "Confirm your new TPIN";
return AppLocalizations.of(context).confirmNewTpin;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Set TPIN')),
appBar: AppBar(title: Text(AppLocalizations.of(context).setTpin)),
body: SafeArea(
child: Column(
children: [

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:kmobile/api/services/auth_service.dart';
import 'package:kmobile/api/services/payment_service.dart';
@@ -45,7 +47,8 @@ class _TransactionPinScreen extends State<TransactionPinScreen> {
if (mounted) {
setState(() => _loading = false);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Failed to check TPIN status')),
SnackBar(
content: Text(AppLocalizations.of(context).tpinStatusFailed)),
);
}
}
@@ -91,7 +94,9 @@ class _TransactionPinScreen extends State<TransactionPinScreen> {
await sendTransaction();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Please enter a 6-digit TPIN")),
SnackBar(
content:
Text(AppLocalizations.of(context).enter6DigitTpin)),
);
}
} else {
@@ -131,12 +136,13 @@ class _TransactionPinScreen extends State<TransactionPinScreen> {
final transfer = widget.transactionData;
transfer.tpin = _pin.join();
try {
final paymentResponse = paymentService.processQuickPayWithinBank(transfer);
final paymentResponse =
paymentService.processQuickPayWithinBank(transfer);
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => PaymentAnimationScreen(paymentResponse: paymentResponse)
),
builder: (_) =>
PaymentAnimationScreen(paymentResponse: paymentResponse)),
);
} catch (e) {
if (mounted) {
@@ -157,28 +163,28 @@ class _TransactionPinScreen extends State<TransactionPinScreen> {
Navigator.pop(context);
},
),
title: const Text(
'TPIN',
title: Text(
AppLocalizations.of(context).tpin,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
),
body: Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Column(
children: [
const Spacer(),
const Text(
'Enter Your TPIN',
style: TextStyle(fontSize: 18),
),
const SizedBox(height: 20),
_buildPinIndicators(),
const Spacer(),
_buildKeypad(),
],
),
padding: const EdgeInsets.only(bottom: 20.0),
child: Column(
children: [
const Spacer(),
Text(
AppLocalizations.of(context).enterTpin,
style: TextStyle(fontSize: 18),
),
const SizedBox(height: 20),
_buildPinIndicators(),
const Spacer(),
_buildKeypad(),
],
),
),
);
}
}

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
@@ -57,8 +59,8 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
),
),
const SizedBox(height: 24),
const Text(
"Transaction Successful",
Text(
AppLocalizations.of(context).transactionSuccess,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
@@ -76,7 +78,7 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
),
const SizedBox(height: 16),
Text(
"To Account Number: $creditAccount",
"${AppLocalizations.of(context).toAccountNumber}: $creditAccount",
style: const TextStyle(
fontSize: 12,
color: Colors.black87,
@@ -98,7 +100,7 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
child: OutlinedButton.icon(
onPressed: _shareScreenshot,
icon: const Icon(Icons.share, size: 18),
label: const Text("Share"),
label: Text(AppLocalizations.of(context).share),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
padding: const EdgeInsets.symmetric(vertical: 16),
@@ -126,7 +128,7 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
backgroundColor: Colors.blue[900],
foregroundColor: Colors.white,
),
child: const Text("Done"),
child: Text(AppLocalizations.of(context).done),
),
),
],

View File

@@ -1,9 +1,10 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutter_swipe_button/flutter_swipe_button.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
class QuickPayOutsideBankScreen extends StatefulWidget {
final String debitAccount;
const QuickPayOutsideBankScreen({super.key, required this.debitAccount});
@@ -26,8 +27,28 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
final phoneController = TextEditingController();
final amountController = TextEditingController();
String accountType = 'Savings';
final List<String> transactionModes = ['NEFT', 'RTGS', 'IMPS'];
//String accountType = 'Savings';
late String accountType;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
accountType = AppLocalizations.of(context).savings;
});
});
}
//final List<String> transactionModes = ['NEFT', 'RTGS', 'IMPS'];
List<String> transactionModes(BuildContext context) {
return [
AppLocalizations.of(context).neft,
AppLocalizations.of(context).rtgs,
AppLocalizations.of(context).imps,
];
}
int selectedTransactionIndex = 0;
@override
@@ -54,8 +75,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
Navigator.pop(context);
},
),
title: const Text(
'Quick Pay - Outside Bank',
title: Text(
AppLocalizations.of(context).quickPayOutsideBank,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
@@ -84,17 +105,18 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
const SizedBox(height: 10),
Row(
children: [
const Text('Debit from:'),
Text(AppLocalizations.of(context).debitFrom),
Text(
widget.debitAccount,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
)
],
),
const SizedBox(height: 20),
TextFormField(
decoration: const InputDecoration(
labelText: 'Account Number',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).accountNumber,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -112,9 +134,9 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Account number is required';
return AppLocalizations.of(context).accountNumberRequired;
} else if (value.length != 11) {
return 'Enter a valid account number';
return AppLocalizations.of(context).validAccountNumber;
}
return null;
},
@@ -122,8 +144,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
const SizedBox(height: 24),
TextFormField(
controller: confirmAccountNumberController,
decoration: const InputDecoration(
labelText: 'Confirm Account Number',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).confirmAccountNumber,
// prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
isDense: true,
@@ -140,18 +162,18 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Re-enter account number';
return AppLocalizations.of(context).reenterAccountNumber;
}
if (value != accountNumberController.text) {
return 'Account numbers do not match';
return AppLocalizations.of(context).accountMismatch;
}
return null;
},
),
const SizedBox(height: 25),
TextFormField(
decoration: const InputDecoration(
labelText: 'Name',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).name,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -168,15 +190,15 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Name is required';
return AppLocalizations.of(context).nameRequired;
}
return null;
},
),
const SizedBox(height: 25),
TextFormField(
decoration: const InputDecoration(
labelText: "Beneficiary Bank Name",
decoration: InputDecoration(
labelText: AppLocalizations.of(context).bankName,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -192,15 +214,15 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Beneficiary Bank Name is required';
return AppLocalizations.of(context).bankNameRequired;
}
return null;
},
),
const SizedBox(height: 25),
TextFormField(
decoration: const InputDecoration(
labelText: "Branch Name",
decoration: InputDecoration(
labelText: AppLocalizations.of(context).branchName,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -216,7 +238,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Branch Name is required';
return AppLocalizations.of(context).branchNameRequired;
}
return null;
},
@@ -226,8 +248,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
children: [
Expanded(
child: TextFormField(
decoration: const InputDecoration(
labelText: "IFSC Code",
decoration: InputDecoration(
labelText: AppLocalizations.of(context).ifscCode,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -243,7 +265,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'IFSC Code is required';
return AppLocalizations.of(context).ifscRequired;
}
return null;
},
@@ -252,8 +274,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
Expanded(
child: DropdownButtonFormField<String>(
value: accountType,
decoration: const InputDecoration(
labelText: "Account Type",
decoration: InputDecoration(
labelText: AppLocalizations.of(context).accountType,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -265,7 +287,10 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
borderSide: BorderSide(color: Colors.black, width: 2),
),
),
items: ['Savings', 'Current']
items: [
AppLocalizations.of(context).savings,
AppLocalizations.of(context).current
]
.map((e) => DropdownMenuItem(
value: e,
child: Text(e),
@@ -285,8 +310,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
child: TextFormField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: "Phone",
decoration: InputDecoration(
labelText: AppLocalizations.of(context).phone,
prefixIcon: Icon(Icons.phone),
border: OutlineInputBorder(),
isDense: true,
@@ -301,15 +326,15 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
),
textInputAction: TextInputAction.next,
validator: (value) => value == null || value.isEmpty
? "Phone number is Required"
? AppLocalizations.of(context).phoneRequired
: null,
),
),
const SizedBox(width: 10),
Expanded(
child: TextFormField(
decoration: const InputDecoration(
labelText: 'Amount',
decoration: InputDecoration(
labelText: AppLocalizations.of(context).amount,
border: OutlineInputBorder(),
isDense: true,
filled: true,
@@ -326,11 +351,11 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Amount is required';
return AppLocalizations.of(context).amountRequired;
}
final amount = double.tryParse(value);
if (amount == null || amount <= 0) {
return 'Enter a valid amount';
return AppLocalizations.of(context).validAmount;
}
return null;
},
@@ -341,7 +366,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
const SizedBox(height: 30),
Row(
children: [
const Text("Transaction Mode",
Text(AppLocalizations.of(context).transactionMode,
style: TextStyle(fontWeight: FontWeight.w500)),
const SizedBox(width: 12),
Expanded(child: buildTransactionModeSelector()),
@@ -359,8 +384,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
activeTrackColor: Colors.blue.shade100,
borderRadius: BorderRadius.circular(30),
height: 56,
child: const Text(
"Swipe to Pay",
child: Text(
AppLocalizations.of(context).swipeToPay,
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
@@ -368,10 +393,11 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
if (_formKey.currentState!.validate()) {
// Perform payment logic
final selectedMode =
transactionModes[selectedTransactionIndex];
transactionModes(context)[selectedTransactionIndex];
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Paying via $selectedMode...')),
content: Text(
'${AppLocalizations.of(context).payingVia} $selectedMode...')),
);
// Navigator.push(
// context,
@@ -395,7 +421,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
return Container(
padding: const EdgeInsets.all(4),
child: Row(
children: List.generate(transactionModes.length, (index) {
children: List.generate(transactionModes(context).length, (index) {
bool isSelected = selectedTransactionIndex == index;
return Expanded(
child: GestureDetector(
@@ -415,7 +441,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
),
alignment: Alignment.center,
child: Text(
transactionModes[index],
transactionModes(context)[index],
style: const TextStyle(
color: Colors.black,
),

View File

@@ -1,3 +1,5 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
@@ -8,14 +10,16 @@ class ServiceScreen extends StatefulWidget {
State<ServiceScreen> createState() => _ServiceScreen();
}
class _ServiceScreen extends State<ServiceScreen>{
class _ServiceScreen extends State<ServiceScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text('Services', style: TextStyle(color: Colors.black,
fontWeight: FontWeight.w500),),
title: Text(
AppLocalizations.of(context).services,
style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
),
centerTitle: false,
actions: [
// IconButton(
@@ -28,61 +32,53 @@ class _ServiceScreen extends State<ServiceScreen>{
padding: const EdgeInsets.only(right: 10.0),
child: InkWell(
borderRadius: BorderRadius.circular(20),
onTap: (){
onTap: () {
// Navigator.push(context, MaterialPageRoute(
// builder: (context) => const CustomerInfoScreen()));
},
child: const CircleAvatar(
backgroundImage: AssetImage('assets/images/avatar.jpg'), // Replace with your image
backgroundImage: AssetImage(
'assets/images/avatar.jpg'), // Replace with your image
radius: 20,
),
),
),
],
),
body: ListView(
children: [
ServiceManagementTile(
icon: Symbols.add,
label: 'Account Opening Request - Deposit',
onTap: () {
},
label: AppLocalizations.of(context).accountOpeningDeposit,
onTap: () {},
),
const Divider(
height: 1,
),
const Divider(height: 1,),
ServiceManagementTile(
icon: Symbols.add,
label: 'Account Opening Request - Loan',
onTap: () {
},
label: AppLocalizations.of(context).accountOpeningLoan,
onTap: () {},
),
const Divider(
height: 1,
),
const Divider(height: 1,),
ServiceManagementTile(
icon: Symbols.captive_portal,
label: 'Quick Links',
onTap: () {
},
label: AppLocalizations.of(context).quickLinks,
onTap: () {},
),
const Divider(
height: 1,
),
const Divider(height: 1,),
ServiceManagementTile(
icon: Symbols.missing_controller,
label: 'Branch Locator',
onTap: () {
},
label: AppLocalizations.of(context).branchLocator,
onTap: () {},
),
const Divider(height: 1,)
const Divider(
height: 1,
)
],
),
);
@@ -110,4 +106,4 @@ class ServiceManagementTile extends StatelessWidget {
onTap: onTap,
);
}
}
}

View File

@@ -194,6 +194,31 @@
"transactionSuccess": "Transaction Successful",
"on": "On",
"toAccountNumber": "To Account Number",
"shareText": "Share"
"shareText": "Share",
"enableFingerprintLogin": "Enable Fingerprint Login?",
"enableFingerprintMessage": "Would you like to enable fingerprint authentication for faster login?",
"no": "No",
"yes": "Yes",
"authenticateToEnable": "Authenticate to enable fingerprint login",
"exitApp": "Exit App",
"exitConfirmation": "Do you really want to exit?",
"loading": "Loading......",
"enableFingerprintQuick": "Enable fingerprint authentication for quick login?",
"kccb": "KCCB",
"password": "Password",
"pleaseEnterUsername": "Please enter your username",
"pleaseEnterPassword": "Please enter your password",
"login": "Login",
"or": "OR",
"register": "Register",
"authenticateToAccess": "Authenticate to access kmobile",
"incorrectMPIN": "Incorrect mPIN. Try again.",
"pinsDoNotMatch": "PINs do not match. Try again.",
"pleaseEnter4Digits": "Please enter 4 digits.",
"enterMPIN": "Enter your mPIN",
"setMPIN": "Set your mPIN",
"confirmMPIN": "Confirm your mPIN",
"kconnect": "Kconnect",
"kccBankFull": "Kangra Central Co-operative Bank"
}

View File

@@ -194,5 +194,30 @@
"transactionSuccess": "लेन-देन सफल रहा",
"on": "पर",
"toAccountNumber": "खाते संख्या में",
"shareText": "साझा करें"
}
"shareText": "साझा करें",
"enableFingerprintLogin": "फिंगरप्रिंट लॉगिन सक्षम करें?",
"enableFingerprintMessage": "क्या आप तेज लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करना चाहेंगे?",
"no": "नहीं",
"yes": "हाँ",
"authenticateToEnable": "फिंगरप्रिंट लॉगिन सक्षम करने के लिए प्रमाणीकरण करें",
"exitApp": "ऐप बंद करें",
"exitConfirmation": "क्या आप वाकई ऐप से बाहर निकलना चाहते हैं?",
"loading": "लोड हो रहा है......",
"enableFingerprintQuick": "तेज़ लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करें?",
"kccb": "केसीसीबी",
"password": "पासवर्ड",
"pleaseEnterUsername": "कृपया उपयोगकर्ता नाम दर्ज करें",
"pleaseEnterPassword": "कृपया पासवर्ड दर्ज करें",
"login": "लॉगिन",
"or": "या",
"register": "रजिस्टर करें",
"authenticateToAccess": "kmobile तक पहुंच के लिए प्रमाणीकरण करें",
"incorrectMPIN": "गलत mPIN. कृपया पुनः प्रयास करें।",
"pinsDoNotMatch": "PIN मेल नहीं खा रहे हैं। पुनः प्रयास करें।",
"pleaseEnter4Digits": "कृपया 4 अंक दर्ज करें।",
"enterMPIN": "अपना mPIN दर्ज करें",
"setMPIN": "अपना mPIN सेट करें",
"confirmMPIN": "अपना mPIN की पुष्टि करें",
"kconnect": "केकनेक्ट",
"kccBankFull": "कांगड़ा सेंट्रल को-ऑपरेटिव बैंक"
}