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

@@ -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),
),
),
],