Language Change
This commit is contained in:
@@ -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(
|
||||
|
@@ -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),
|
||||
|
@@ -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),
|
||||
],
|
||||
|
@@ -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],
|
||||
|
@@ -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: [
|
||||
|
@@ -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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
Reference in New Issue
Block a user