Fromatting and localizations

This commit is contained in:
2025-12-31 12:44:39 +05:30
parent 60270a5fa9
commit 54a7b8f1b0
21 changed files with 501 additions and 194 deletions

View File

@@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
class Cheque { class Cheque {
final String? type; final String? type;
final String? InstrType; final String? InstrType;
@@ -17,19 +18,19 @@ class Cheque {
final String? StopExpiryDate; final String? StopExpiryDate;
Cheque({ Cheque({
this.type, this.type,
this.InstrType, this.InstrType,
this.Date, this.Date,
this.branchCode, this.branchCode,
this.fromCheque, this.fromCheque,
this.toCheque, this.toCheque,
this.Chequescount, this.Chequescount,
this.ChequeNumber, this.ChequeNumber,
this.transactionCode, this.transactionCode,
this.amount, this.amount,
this.status, this.status,
this.stopIssueDate, this.stopIssueDate,
this.StopExpiryDate, this.StopExpiryDate,
}); });
factory Cheque.fromJson(Map<String, dynamic> json) { factory Cheque.fromJson(Map<String, dynamic> json) {
@@ -61,8 +62,8 @@ class ChequeService {
final Dio _dio; final Dio _dio;
ChequeService(this._dio); ChequeService(this._dio);
Future<List<Cheque>> ChequeEnquiry( Future<List<Cheque>> ChequeEnquiry({
{required String accountNumber, required String accountNumber,
required String instrType, required String instrType,
}) async { }) async {
try { try {
@@ -80,13 +81,15 @@ class ChequeService {
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
if (response.data is Map<String, dynamic> && response.data.containsKey('records')) { if (response.data is Map<String, dynamic> &&
response.data.containsKey('records')) {
final records = response.data['records']; final records = response.data['records'];
if (records is List) { if (records is List) {
return Cheque.listFromJson(records); return Cheque.listFromJson(records);
} }
} }
throw Exception("Unexpected API response format: 'records' list not found or malformed"); throw Exception(
"Unexpected API response format: 'records' list not found or malformed");
} else { } else {
throw Exception("Failed to fetch"); throw Exception("Failed to fetch");
} }
@@ -110,12 +113,10 @@ class ChequeService {
}) async { }) async {
final response = await _dio.post( final response = await _dio.post(
'/api/cheque/stop', '/api/cheque/stop',
options: Options( options: Options(
validateStatus: (int? status) => true, validateStatus: (int? status) => true,
receiveDataWhenStatusError: true, receiveDataWhenStatusError: true,
), ),
data: { data: {
'accountNumber': accountno, 'accountNumber': accountno,
'stopFromChequeNo': stopFromChequeNo, 'stopFromChequeNo': stopFromChequeNo,
@@ -126,7 +127,7 @@ class ChequeService {
'stopAmount': stopAmount, 'stopAmount': stopAmount,
'stopComment': stopComment, 'stopComment': stopComment,
'chqIssueDate': chequeIssueDate, 'chqIssueDate': chequeIssueDate,
'tpin':tpin, 'tpin': tpin,
}, },
); );
if (response.statusCode != 200) { if (response.statusCode != 200) {

View File

@@ -147,7 +147,8 @@ class _ManageBeneficiariesScreen extends State<ManageBeneficiariesScreen> {
child: TextField( child: TextField(
controller: _searchController, controller: _searchController,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search by name or account number", hintText:
AppLocalizations.of(context).searchByNameOrAccountHint,
prefixIcon: const Icon(Icons.search), prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:kmobile/api/services/cheque_service.dart'; import 'package:kmobile/api/services/cheque_service.dart';
import 'package:kmobile/data/models/user.dart'; import 'package:kmobile/data/models/user.dart';
import 'package:kmobile/di/injection.dart'; import 'package:kmobile/di/injection.dart';
import 'package:kmobile/l10n/app_localizations.dart';
class ChequeEnquiryScreen extends StatefulWidget { class ChequeEnquiryScreen extends StatefulWidget {
final List<User> users; final List<User> users;
@@ -119,7 +120,8 @@ class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
} else { } else {
filteredCheques = _allCheques.where((cheque) { filteredCheques = _allCheques.where((cheque) {
final lowerQuery = query.toLowerCase(); final lowerQuery = query.toLowerCase();
return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ?? false) || return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ??
false) ||
(cheque.status?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.status?.toLowerCase().contains(lowerQuery) ?? false) ||
(cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) || (cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) ||
(cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false); (cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false);
@@ -142,7 +144,7 @@ class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Cheque Enquiry'), title: Text(AppLocalizations.of(context).chequeEnquiryTitle),
centerTitle: false, centerTitle: false,
), ),
body: Stack( body: Stack(
@@ -159,9 +161,9 @@ class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Text(
"Account Number", AppLocalizations.of(context).accountNumber,
style: TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18), fontWeight: FontWeight.bold, fontSize: 18),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
@@ -199,9 +201,10 @@ class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: TextField( child: TextField(
controller: _searchController, controller: _searchController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Search by Cheque Details', labelText: AppLocalizations.of(context)
prefixIcon: Icon(Icons.search), .searchByChequeDetailsHint,
prefixIcon: const Icon(Icons.search),
border: InputBorder border: InputBorder
.none, // Remove border to make it look like it's inside the card .none, // Remove border to make it look like it's inside the card
), ),
@@ -213,7 +216,9 @@ class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
child: _isLoading child: _isLoading
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: _groupedCheques.isEmpty : _groupedCheques.isEmpty
? const Center(child: Text('No cheque status found.')) ? Center(
child: Text(AppLocalizations.of(context)
.noChequeStatusFound))
: ListView( : ListView(
children: _groupedCheques.entries.map((entry) { children: _groupedCheques.entries.map((entry) {
return Column( return Column(
@@ -281,7 +286,7 @@ class ChequeStatusTile extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Chequebook Issued (CI)', Text(AppLocalizations.of(context).chequebookIssuedLabel,
style: Theme.of(context).textTheme.titleLarge), style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 8), const SizedBox(height: 8),
_buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('Branch Code:', cheque.branchCode),
@@ -303,7 +308,7 @@ class ChequeStatusTile extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Presented Cheque (PR)', Text(AppLocalizations.of(context).presentedChequeLabel,
style: Theme.of(context).textTheme.titleLarge), style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 8), const SizedBox(height: 8),
_buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('Branch Code:', cheque.branchCode),
@@ -326,7 +331,7 @@ class ChequeStatusTile extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Stop Cheque (ST)', Text(AppLocalizations.of(context).stopChequeLabel,
style: Theme.of(context).textTheme.titleLarge), style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 8), const SizedBox(height: 8),
_buildInfoRow('Branch Code:', cheque.branchCode), _buildInfoRow('Branch Code:', cheque.branchCode),

View File

@@ -41,9 +41,9 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
Expanded( Expanded(
child: ChequeManagementCardTile( child: ChequeManagementCardTile(
icon: Symbols.payments, icon: Symbols.payments,
label: "Cheque Enquiry", label: AppLocalizations.of(context).chequeEnquiryTitle,
subtitle: subtitle:
"You can view the status of your issued cheque book, presented cheques and details of stopped cheques including relevant dates, cheque numbers and other essential information", AppLocalizations.of(context).chequeEnquirySubtitle,
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
@@ -61,8 +61,7 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
child: ChequeManagementCardTile( child: ChequeManagementCardTile(
icon: Symbols.block_sharp, icon: Symbols.block_sharp,
label: AppLocalizations.of(context).stopCheque, label: AppLocalizations.of(context).stopCheque,
subtitle: subtitle: AppLocalizations.of(context).stopChequeSubtitle,
"Initiate stop for one or more cheques from your issued checkbook. This essential service helps prevent unauthorized transactions and protects against fraud.",
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
@@ -138,8 +137,9 @@ class ChequeManagementCardTile extends StatelessWidget {
Icon( Icon(
icon, icon,
size: 48, // Make icon larger size: 48, // Make icon larger
color: color: disable
disable ? theme.disabledColor : theme.colorScheme.primary, ? theme.disabledColor
: theme.colorScheme.primary,
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(

View File

@@ -120,7 +120,7 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Stop Cheque'), title: Text(AppLocalizations.of(context).stopChequeTitle),
centerTitle: false, centerTitle: false,
), ),
body: Stack( body: Stack(
@@ -137,9 +137,9 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Text(
"Account Number", AppLocalizations.of(context).accountNumber,
style: TextStyle( style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18), fontWeight: FontWeight.bold, fontSize: 18),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
@@ -164,7 +164,7 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
), ),
) )
else else
const Text('No accounts found'), Text(AppLocalizations.of(context).noAccountsFound),
], ],
), ),
), ),
@@ -182,8 +182,7 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) => StopSingleChequeScreen(
StopSingleChequeScreen(
selectedAccount: _selectedAccount!, selectedAccount: _selectedAccount!,
date: _ciCheque!.Date!, date: _ciCheque!.Date!,
instrType: _ciCheque!.InstrType!, instrType: _ciCheque!.InstrType!,
@@ -194,9 +193,9 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
); );
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text( content: Text(AppLocalizations.of(context)
'No cheque book found to stop cheques from.'), .noChequebookToStop),
), ),
); );
} }
@@ -205,7 +204,8 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Center( child: Center(
child: Text( child: Text(
'Stop Single Cheque', AppLocalizations.of(context)
.stopSingleChequeTitle,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
@@ -223,8 +223,7 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded( Expanded(
child: Card( child: Card(
color: color: Theme.of(context).colorScheme.primaryContainer,
Theme.of(context).colorScheme.primaryContainer,
elevation: 4, elevation: 4,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
@@ -244,9 +243,9 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
); );
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( SnackBar(
content: Text( content: Text(AppLocalizations.of(context)
'Please select an account first.'), .pleaseSelectAccountFirst),
), ),
); );
} }
@@ -255,7 +254,8 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Center( child: Center(
child: Text( child: Text(
'Stop Multiple Cheques', AppLocalizations.of(context)
.stopMultipleChequesButton,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
@@ -277,8 +277,9 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
child: _isLoading child: _isLoading
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: _ciCheque == null : _ciCheque == null
? const Center( ? Center(
child: Text('No Cheque Issued status found.')) child: Text(AppLocalizations.of(context)
.noChequeIssuedStatus))
: _buildCiTile(context, _ciCheque!), : _buildCiTile(context, _ciCheque!),
), ),
], ],
@@ -313,7 +314,7 @@ class _StopChequeScreenState extends State<StopChequeScreen> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Chequebook Details', Text(AppLocalizations.of(context).chequebookDetailsTitle,
style: Theme.of(context).textTheme.titleLarge), style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 8), const SizedBox(height: 8),
_buildInfoRow('Account Number:', _selectedAccount!.accountNo!), _buildInfoRow('Account Number:', _selectedAccount!.accountNo!),

View File

@@ -5,6 +5,7 @@ import 'package:kmobile/api/services/cheque_service.dart';
import 'package:kmobile/data/models/user.dart'; import 'package:kmobile/data/models/user.dart';
import 'package:kmobile/di/injection.dart'; import 'package:kmobile/di/injection.dart';
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
import 'package:kmobile/l10n/app_localizations.dart';
class StopMultipleChequesScreen extends StatefulWidget { class StopMultipleChequesScreen extends StatefulWidget {
final User selectedAccount; final User selectedAccount;
@@ -13,7 +14,6 @@ class StopMultipleChequesScreen extends StatefulWidget {
final String fromCheque; final String fromCheque;
final String toCheque; final String toCheque;
const StopMultipleChequesScreen( const StopMultipleChequesScreen(
{super.key, {super.key,
required this.selectedAccount, required this.selectedAccount,
@@ -82,7 +82,7 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Stop Multiple Cheques'), title: Text(AppLocalizations.of(context).stopMultipleChequesTitle),
), ),
body: Padding( body: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
@@ -100,20 +100,22 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
height: 40, height: 40,
), ),
title: Text(widget.selectedAccount.accountNo!), title: Text(widget.selectedAccount.accountNo!),
subtitle: const Text("Account Number"), subtitle:
Text(AppLocalizations.of(context).accountNumberTitle),
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
TextFormField( TextFormField(
controller: _stopFromChequeNoController, controller: _stopFromChequeNoController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'From Cheque Number *', labelText: AppLocalizations.of(context).fromChequeNumberHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Please enter a cheque number'; return AppLocalizations.of(context)
.pleaseEnterChequeNumberError;
} }
final chequeNumber = int.tryParse(value); final chequeNumber = int.tryParse(value);
final fromCheque = int.tryParse(widget.fromCheque); final fromCheque = int.tryParse(widget.fromCheque);
@@ -121,10 +123,12 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
if (chequeNumber == null || if (chequeNumber == null ||
fromCheque == null || fromCheque == null ||
toCheque == null) { toCheque == null) {
return 'Invalid cheque number format'; return AppLocalizations.of(context)
.invalidChequeNumberFormatError;
} }
if (chequeNumber < fromCheque || chequeNumber > toCheque) { if (chequeNumber < fromCheque || chequeNumber > toCheque) {
return 'Cheque number must be between ${widget.fromCheque} and ${widget.toCheque}'; return AppLocalizations.of(context).chequeNumberRangeError(
widget.fromCheque, widget.toCheque);
} }
return null; return null;
}, },
@@ -132,14 +136,15 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopToChequeNoController, controller: _stopToChequeNoController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'To Cheque Number *', labelText: AppLocalizations.of(context).toChequeNumberHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Please enter a cheque number'; return AppLocalizations.of(context)
.pleaseEnterChequeNumberError;
} }
final chequeNumber = int.tryParse(value); final chequeNumber = int.tryParse(value);
final fromCheque = int.tryParse(widget.fromCheque); final fromCheque = int.tryParse(widget.fromCheque);
@@ -147,10 +152,12 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
if (chequeNumber == null || if (chequeNumber == null ||
fromCheque == null || fromCheque == null ||
toCheque == null) { toCheque == null) {
return 'Invalid cheque number format'; return AppLocalizations.of(context)
.invalidChequeNumberFormatError;
} }
if (chequeNumber < fromCheque || chequeNumber > toCheque) { if (chequeNumber < fromCheque || chequeNumber > toCheque) {
return 'Cheque number must be between ${widget.fromCheque} and ${widget.toCheque}'; return AppLocalizations.of(context).chequeNumberRangeError(
widget.fromCheque, widget.toCheque);
} }
return null; return null;
}, },
@@ -159,53 +166,54 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
TextFormField( TextFormField(
initialValue: widget.instrType, initialValue: widget.instrType,
readOnly: true, readOnly: true,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Instrument Type *', labelText: AppLocalizations.of(context).instrumentTypeLabel,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopIssueDateController, controller: _stopIssueDateController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Issue Date', labelText: AppLocalizations.of(context).stopIssueDateHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.datetime, keyboardType: TextInputType.datetime,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopExpiryDateController, controller: _stopExpiryDateController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Expiry Date', labelText: AppLocalizations.of(context).stopExpiryDateHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.datetime, keyboardType: TextInputType.datetime,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopAmountController, controller: _stopAmountController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Amount', labelText: AppLocalizations.of(context).stopAmountHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopCommentController, controller: _stopCommentController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Comment', labelText: AppLocalizations.of(context).stopCommentHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
initialValue: _formatDate(widget.date), initialValue: _formatDate(widget.date),
readOnly: true, readOnly: true,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Chequebook Issue Date', labelText:
border: OutlineInputBorder(), AppLocalizations.of(context).chequebookIssueDateHint,
border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
@@ -224,11 +232,9 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
stopFromChequeNo: stopFromChequeNo:
_stopFromChequeNoController.text, _stopFromChequeNoController.text,
instrType: widget.instrType, instrType: widget.instrType,
stopToChequeNo: stopToChequeNo: _stopToChequeNoController.text,
_stopToChequeNoController.text,
stopIssueDate: _stopIssueDateController.text, stopIssueDate: _stopIssueDateController.text,
stopExpiryDate: stopExpiryDate: _stopExpiryDateController.text,
_stopExpiryDateController.text,
stopAmount: _stopAmountController.text, stopAmount: _stopAmountController.text,
stopComment: _stopCommentController.text, stopComment: _stopCommentController.text,
chequeIssueDate: widget.date, chequeIssueDate: widget.date,
@@ -248,9 +254,11 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
print(e.toString()); print(e.toString());
try { try {
final errorBodyString = e.toString().split('Exception: ')[1]; final errorBodyString =
e.toString().split('Exception: ')[1];
final errorBody = jsonDecode(errorBodyString); final errorBody = jsonDecode(errorBodyString);
if (errorBody.containsKey('error') && errorBody['error'] == 'INCORRECT_TPIN') { if (errorBody.containsKey('error') &&
errorBody['error'] == 'INCORRECT_TPIN') {
_showResponseDialog('Invalid TPIN', _showResponseDialog('Invalid TPIN',
'The TPIN you entered is incorrect. Please try again.'); 'The TPIN you entered is incorrect. Please try again.');
} else { } else {
@@ -268,7 +276,7 @@ class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
); );
} }
}, },
child: const Text('Stop Cheque'), child: Text(AppLocalizations.of(context).stopChequeButton),
), ),
], ],
), ),

View File

@@ -4,6 +4,7 @@ import 'package:kmobile/di/injection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:kmobile/api/services/cheque_service.dart'; import 'package:kmobile/api/services/cheque_service.dart';
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
import 'package:kmobile/l10n/app_localizations.dart';
class StopSingleChequeScreen extends StatefulWidget { class StopSingleChequeScreen extends StatefulWidget {
final User selectedAccount; final User selectedAccount;
@@ -63,7 +64,7 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
), ),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: const Text('Close'), child: Text(AppLocalizations.of(context).closeButton),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@@ -78,7 +79,7 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Stop Single Cheque'), title: Text(AppLocalizations.of(context).stopSingleChequeTitle),
), ),
body: Padding( body: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
@@ -96,20 +97,22 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
height: 40, height: 40,
), ),
title: Text(widget.selectedAccount.accountNo!), title: Text(widget.selectedAccount.accountNo!),
subtitle: const Text("Account Number"), subtitle:
Text(AppLocalizations.of(context).accountNumberLabel),
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
TextFormField( TextFormField(
controller: _stopFromChequeNoController, controller: _stopFromChequeNoController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Cheque Number *', labelText: AppLocalizations.of(context).chequeNumberLabel,
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'Please enter a cheque number'; return AppLocalizations.of(context)
.pleaseEnterChequeNumberError;
} }
final chequeNumber = int.tryParse(value); final chequeNumber = int.tryParse(value);
final fromCheque = int.tryParse(widget.fromCheque); final fromCheque = int.tryParse(widget.fromCheque);
@@ -117,10 +120,12 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
if (chequeNumber == null || if (chequeNumber == null ||
fromCheque == null || fromCheque == null ||
toCheque == null) { toCheque == null) {
return 'Invalid cheque number format'; return AppLocalizations.of(context)
.invalidChequeNumberFormatError;
} }
if (chequeNumber < fromCheque || chequeNumber > toCheque) { if (chequeNumber < fromCheque || chequeNumber > toCheque) {
return 'Cheque number must be between ${widget.fromCheque} and ${widget.toCheque}'; return AppLocalizations.of(context).chequeNumberRangeError(
widget.fromCheque, widget.toCheque);
} }
return null; return null;
}, },
@@ -129,53 +134,54 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
TextFormField( TextFormField(
initialValue: widget.instrType, initialValue: widget.instrType,
readOnly: true, readOnly: true,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Instrument Type *', labelText: AppLocalizations.of(context).instrumentTypeLabel,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopIssueDateController, controller: _stopIssueDateController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Issue Date', labelText: AppLocalizations.of(context).stopIssueDateLabel,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.datetime, keyboardType: TextInputType.datetime,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopExpiryDateController, controller: _stopExpiryDateController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Expiry Date', labelText: AppLocalizations.of(context).stopExpiryDateLabel,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.datetime, keyboardType: TextInputType.datetime,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopAmountController, controller: _stopAmountController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Amount', labelText: AppLocalizations.of(context).stopAmountHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
controller: _stopCommentController, controller: _stopCommentController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Stop Comment', labelText: AppLocalizations.of(context).stopCommentHint,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
initialValue: _formatDate(widget.date), initialValue: _formatDate(widget.date),
readOnly: true, readOnly: true,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: 'Chequebook Issue Date', labelText:
border: OutlineInputBorder(), AppLocalizations.of(context).chequebookIssueDateHint,
border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
@@ -197,8 +203,7 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
stopToChequeNo: stopToChequeNo:
_stopFromChequeNoController.text, _stopFromChequeNoController.text,
stopIssueDate: _stopIssueDateController.text, stopIssueDate: _stopIssueDateController.text,
stopExpiryDate: stopExpiryDate: _stopExpiryDateController.text,
_stopExpiryDateController.text,
stopAmount: _stopAmountController.text, stopAmount: _stopAmountController.text,
stopComment: _stopCommentController.text, stopComment: _stopCommentController.text,
chequeIssueDate: widget.date, chequeIssueDate: widget.date,
@@ -218,9 +223,11 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
print(e.toString()); print(e.toString());
try { try {
final errorBodyString = e.toString().split('Exception: ')[1]; final errorBodyString =
e.toString().split('Exception: ')[1];
final errorBody = jsonDecode(errorBodyString); final errorBody = jsonDecode(errorBodyString);
if (errorBody.containsKey('error') && errorBody['error'] == 'INCORRECT_TPIN') { if (errorBody.containsKey('error') &&
errorBody['error'] == 'INCORRECT_TPIN') {
_showResponseDialog('Invalid TPIN', _showResponseDialog('Invalid TPIN',
'The TPIN you entered is incorrect. Please try again.'); 'The TPIN you entered is incorrect. Please try again.');
} else { } else {
@@ -238,7 +245,7 @@ class _StopSingleChequeScreenState extends State<StopSingleChequeScreen> {
); );
} }
}, },
child: const Text('Stop Cheque'), child: Text(AppLocalizations.of(context).stopChequeButton),
), ),
], ],
), ),

View File

@@ -653,8 +653,7 @@ class _DashboardScreenState extends State<DashboardScreen>
MaterialPageRoute( MaterialPageRoute(
builder: (context) => ChequeManagementScreen( builder: (context) => ChequeManagementScreen(
users: users, users: users,
selectedIndex: selectedAccountIndex selectedIndex: selectedAccountIndex),
),
), ),
); );
}, },

View File

@@ -129,7 +129,7 @@ class _EnquiryScreen extends State<EnquiryScreen> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Complaint Form", AppLocalizations.of(context).complaintFormTitle,
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,

View File

@@ -496,7 +496,7 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
Text(AppLocalizations.of(context).fetchingDailyLimit), Text(AppLocalizations.of(context).fetchingDailyLimit),
if (!_isLoadingLimit && _limit != null) if (!_isLoadingLimit && _limit != null)
Text( Text(
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', '${AppLocalizations.of(context).remainingDailyLimit} ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
const Spacer(), const Spacer(),

View File

@@ -198,7 +198,8 @@ class _FundTransferBeneficiaryScreenState
child: TextField( child: TextField(
controller: _searchController, controller: _searchController,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search by name or account number", hintText:
AppLocalizations.of(context).searchByNameOrAccountHint,
prefixIcon: const Icon(Icons.search), prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),

View File

@@ -42,7 +42,7 @@ class FundTransferScreen extends StatelessWidget {
Expanded( Expanded(
child: FundTransferManagementTile( child: FundTransferManagementTile(
icon: Symbols.person, icon: Symbols.person,
label: "Self Pay", label: AppLocalizations.of(context).selfPay,
subtitle: subtitle:
AppLocalizations.of(context).ftselfpaysubtitle, AppLocalizations.of(context).ftselfpaysubtitle,
onTap: () { onTap: () {

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:kmobile/data/models/user.dart'; import 'package:kmobile/data/models/user.dart';
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart';
import 'package:kmobile/l10n/app_localizations.dart';
import 'package:kmobile/widgets/bank_logos.dart'; import 'package:kmobile/widgets/bank_logos.dart';
class FundTransferSelfAccountsScreen extends StatelessWidget { class FundTransferSelfAccountsScreen extends StatelessWidget {
@@ -43,7 +44,7 @@ class FundTransferSelfAccountsScreen extends StatelessWidget {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Select Account"), title: Text(AppLocalizations.of(context).selectAccount),
), ),
body: Stack( body: Stack(
children: [ children: [

View File

@@ -7,6 +7,7 @@ import 'package:kmobile/data/models/user.dart';
import 'package:kmobile/di/injection.dart'; import 'package:kmobile/di/injection.dart';
import 'package:kmobile/features/fund_transfer/screens/payment_animation.dart'; import 'package:kmobile/features/fund_transfer/screens/payment_animation.dart';
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
import 'package:kmobile/l10n/app_localizations.dart';
import 'package:kmobile/widgets/bank_logos.dart'; import 'package:kmobile/widgets/bank_logos.dart';
class FundTransferSelfAmountScreen extends StatefulWidget { class FundTransferSelfAmountScreen extends StatefulWidget {
@@ -134,7 +135,7 @@ class _FundTransferSelfAmountScreenState
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("Fund Transfer"), title: Text(AppLocalizations.of(context).fundTransferTitle),
), ),
body: SafeArea( body: SafeArea(
child: Stack( child: Stack(
@@ -148,7 +149,7 @@ class _FundTransferSelfAmountScreenState
children: [ children: [
// Debit Account (User) // Debit Account (User)
Text( Text(
"Debit From", AppLocalizations.of(context).debitFromLabel,
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
), ),
Card( Card(
@@ -168,7 +169,7 @@ class _FundTransferSelfAmountScreenState
// Credit Account (Self) // Credit Account (Self)
Text( Text(
"Credited To", AppLocalizations.of(context).creditedTo,
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
), ),
Card( Card(
@@ -186,9 +187,10 @@ class _FundTransferSelfAmountScreenState
// Remarks // Remarks
TextFormField( TextFormField(
controller: _remarksController, controller: _remarksController,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: "Remarks (Optional)", labelText:
border: OutlineInputBorder(), AppLocalizations.of(context).remarksOptionalHint,
border: const OutlineInputBorder(),
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
@@ -197,18 +199,18 @@ class _FundTransferSelfAmountScreenState
TextFormField( TextFormField(
controller: _amountController, controller: _amountController,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
decoration: const InputDecoration( decoration: InputDecoration(
labelText: "Amount", labelText: AppLocalizations.of(context).amountLabel,
border: OutlineInputBorder(), border: const OutlineInputBorder(),
prefixIcon: Icon(Icons.currency_rupee), prefixIcon: const Icon(Icons.currency_rupee),
), ),
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return "Amount is required"; return AppLocalizations.of(context).amountRequired;
} }
if (double.tryParse(value) == null || if (double.tryParse(value) == null ||
double.parse(value) <= 0) { double.parse(value) <= 0) {
return "Please enter a valid amount"; return AppLocalizations.of(context).validAmountError;
} }
return null; return null;
}, },
@@ -216,10 +218,12 @@ class _FundTransferSelfAmountScreenState
const SizedBox(height: 8), const SizedBox(height: 8),
// Daily Limit Display // Daily Limit Display
if (_isLoadingLimit) const Text('Fetching daily limit...'), if (_isLoadingLimit)
Text(AppLocalizations.of(context)
.fetchingDailyLimitLoader),
if (!_isLoadingLimit && _limit != null) if (!_isLoadingLimit && _limit != null)
Text( Text(
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', '${AppLocalizations.of(context).remainingDailyLimit} ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
const Spacer(), const Spacer(),
@@ -232,7 +236,7 @@ class _FundTransferSelfAmountScreenState
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
), ),
child: const Text("Proceed"), child: Text(AppLocalizations.of(context).proceedButton),
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),

View File

@@ -83,8 +83,8 @@ class _DailyLimitScreenState extends State<DailyLimitScreen> {
if (value > 200000) { if (value > 200000) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: const Text( content:
"Limit To be Set must be less than 200000"), Text(localizations.limitToBeSetMustBeLessThan200000),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
backgroundColor: theme.colorScheme.error, backgroundColor: theme.colorScheme.error,
), ),
@@ -184,7 +184,7 @@ class _DailyLimitScreenState extends State<DailyLimitScreen> {
if (_currentLimit != null) ...[ if (_currentLimit != null) ...[
const SizedBox(height: 24), const SizedBox(height: 24),
Text( Text(
"Remaining Limit Today", // This should be localized localizations.remainingLimitToday, // This should be localized
style: theme.textTheme.titleMedium, style: theme.textTheme.titleMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),

View File

@@ -76,7 +76,8 @@ class _ATMLocatorScreenState extends State<ATMLocatorScreen> {
onChanged: onChanged:
_filterAtms, // Updated: Call _filterAtms on text change _filterAtms, // Updated: Call _filterAtms on text change
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Name/Address", // Hint text for the search bar hintText: AppLocalizations.of(context)
.nameAddress, // Hint text for the search bar
prefixIcon: const Icon(Icons.search), // Search icon prefixIcon: const Icon(Icons.search), // Search icon
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
@@ -90,9 +91,9 @@ class _ATMLocatorScreenState extends State<ATMLocatorScreen> {
child: _isLoading child: _isLoading
? _buildShimmerList() // Display shimmer while loading ? _buildShimmerList() // Display shimmer while loading
: _filteredAtms.isEmpty : _filteredAtms.isEmpty
? const Center( ? Center(
child: Text( child: Text(AppLocalizations.of(context)
"No matching ATMs found")) // Message if no ATMs found .noMatchingAtmsFound)) // Message if no ATMs found
: ListView.builder( : ListView.builder(
itemCount: _filteredAtms itemCount: _filteredAtms
.length, // Number of items in the filtered list .length, // Number of items in the filtered list

View File

@@ -69,7 +69,7 @@ class _BranchLocatorScreenState extends State<BranchLocatorScreen> {
controller: _searchController, controller: _searchController,
onChanged: _filterBranches, // Updated onChanged: _filterBranches, // Updated
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Branch Name", hintText: AppLocalizations.of(context).searchbranch,
prefixIcon: const Icon(Icons.search), prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
@@ -83,9 +83,9 @@ class _BranchLocatorScreenState extends State<BranchLocatorScreen> {
child: _isLoading child: _isLoading
? _buildShimmerList() // Changed to shimmer ? _buildShimmerList() // Changed to shimmer
: _filteredBranches.isEmpty : _filteredBranches.isEmpty
? const Center( ? Center(
child: Text( child: Text(AppLocalizations.of(context)
"No matching branches found")) // Updated tex .noMatchingBranchesFound)) // Updated tex
: ListView.builder( : ListView.builder(
itemCount: _filteredBranches.length, itemCount: _filteredBranches.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {

View File

@@ -416,5 +416,144 @@
"kycdetails": "KYC Details", "kycdetails": "KYC Details",
"viewall": "View All", "viewall": "View All",
"branchlocator": "Branch Locator", "branchlocator": "Branch Locator",
"atmlocator": "ATM Locator" "atmlocator": "ATM Locator",
"limitSetError": "Limit to be set must be less than {maxAmount}",
"genericError": "Error: {errorMessage}",
"limitUpdatedSuccess": "Limit Updated",
"remainingLimitToday": "Remaining Limit Today",
"branchNameHint": "Branch Name",
"noMatchingBranches": "No matching branches found",
"selfPay": "Self Pay",
"savingsAccountType": "Savings",
"amountExceedsDailyLimit": "Amount exceeds remaining daily limit of ",
"incorrectTpinError": "Please Enter the correct TPIN",
"insufficientFundsError": "Your account does not have sufficient balance",
"somethingWentWrongError": "Something Went Wrong",
"currencyINR": "INR",
"remainingDailyLimit": "Remaining Daily Limit:",
"searchByNameOrAccount": "Search by name or account number",
"beneficiaryCooldownMessage": "Beneficiary will be enabled after the cooldown period.",
"notApplicable": "N/A",
"savingsAccountLabel": "Savings Account",
"loanAccountLabel": "Loan Account",
"termDepositLabel": "Term Deposit",
"recurringDepositLabel": "Recurring Deposit",
"currentAccountLabel": "Current Account",
"unknownAccountLabel": "Unknown Account",
"selectAccountTitle": "Select Account",
"noOtherAccounts": "No other accounts found",
"kccbBankName": "Kangra Central Co-operative Bank",
"fundTransferTitle": "Fund Transfer",
"debitFromLabel": "Debit From",
"creditToLabel": "Credited To",
"remarksOptionalHint": "Remarks (Optional)",
"amountLabel": "Amount",
"amountRequiredError": "Amount is required",
"validAmountError": "Please enter a valid amount",
"fetchingDailyLimitLoader": "Fetching daily limit...",
"proceedButton": "Proceed",
"enterKey": "Enter",
"backKey": "back",
"doneKey": "done",
"transactionDate": "On {date}",
"paymentResultPng": "/payment_result.png",
"rubikFont": "Rubik",
"transactionDateLabel": "Date: {date}",
"utrLabel": "UTR: {utr}",
"searchByNameOrAccountHint": "Search by name or account number",
"savingsAccountDropdown": "Savings",
"beneficiaryExistsError": "Beneficiary already exists",
"somethingWentWrongShort": "Something went Wrong",
"currentAccountDropdown": "Current",
"failedToDeleteBeneficiaryError": "Failed to delete beneficiary: {error}",
"notAvailable": "N/A",
"bankNameLabel": "Bank Name",
"accountNumberLabel": "Account Number",
"accountTypeLabel": "Account Type",
"ifscCodeLabel": "IFSC Code",
"branchNameLabel": "Branch Name",
"enquiryEmailSubject": "Enquiry",
"couldNotOpenEmailApp": "Could not open email app for {email}",
"couldNotOpenDialer": "Could not open dialer for {phone}",
"couldNotLaunchUrl": "Could not launch {url}",
"complaintFormUrl": "https://kccbhp.bank.in/complaint-form/",
"complaintFormTitle": "Complaint Form",
"chairmanEmail": "chairman@kccb.in",
"chairmanPhone": "01892-222677",
"mdEmail": "md@kccb.in",
"mdPhone": "01892-224969",
"gmwEmail": "gmw@kccb.in",
"gmwPhone": "01892-223280",
"gmnEmail": "gmn@kccb.in",
"gmnPhone": "01892-224607",
"atmNameAddressHint": "Name/Address",
"noMatchingAtms": "No matching ATMs found",
"faq1Question": "How do I log in to the mobile banking app?",
"faq1Answer": "You can log in using your customer number and password. Biometric login (fingerprint) and MPIN is also available for supported evices.",
"faq2Question": "Is my banking information secure on this app?",
"faq2Answer": "Yes. We use industry-standard encryption and multi-factor authentication to ensure your data is safe.",
"faq3Question": "How can I check my account balance?",
"faq3Answer": "Once logged in, your account balance will be displayed on the home screen. You can also view detailed balances under the “Accounts” section.",
"faq4Question": "Can I transfer money to other bank accounts?",
"faq4Answer": "Yes. You can use NEFT, RTGS or IMPS to transfer funds to any bank account in India.",
"faq5Question": "How do I view my transaction history?",
"faq5Answer": "Click on the “Account Statement” icon under the Home Screen to view recent and past transactions.",
"chequeEnquiryTitle": "Cheque Enquiry",
"chequeEnquirySubtitle": "You can view the status of your issued cheque book, presented cheques and details of stopped cheques including relevant dates, cheque numbers and other essential information",
"stopChequeSubtitle": "Initiate stop for one or more cheques from your issued checkbook. This essential service helps prevent unauthorized transactions and protects against fraud.",
"chequeEnquiryFailedError": "Failed to fetch cheque status: {error}",
"accountNumberTitle": "Account Number",
"noAccountsFound": "No accounts found",
"searchByChequeDetailsHint": "Search by Cheque Details",
"noChequeStatusFound": "No cheque status found.",
"chequebookIssuedLabel": "Chequebook Issued (CI)",
"branchCodeLabel": "Branch Code:",
"fromChequeLabel": "From Cheque:",
"toChequeLabel": "To Cheque:",
"dateLabel": "Date:",
"chequesCountLabel": "Cheques Count:",
"presentedChequeLabel": "Presented Cheque (PR)",
"chequeNumberLabel": "Cheque Number:",
"transactionCodeLabel": "Transaction Code:",
"amountLabelWithColon": "Amount:",
"statusLabel": "Status:",
"stopChequeLabel": "Stop Cheque (ST)",
"stopIssueDateLabel": "Stop Issue Date:",
"stopExpiryDateLabel": "Stop Expiry Date:",
"emptyString": "",
"cashCreditAccountLabel": "Cash Credit Account",
"stopChequeTitle": "Stop Cheque",
"noChequebookToStop": "No cheque book found to stop cheques from.",
"stopSingleChequeButton": "Stop Single Cheque",
"pleaseSelectAccountFirst": "Please select an account first.",
"stopMultipleChequesButton": "Stop Multiple Cheques",
"noChequeIssuedStatus": "No Cheque Issued status found.",
"chequebookDetailsTitle": "Chequebook Details",
"customerNameLabel": "Customer Name:",
"cifNumberLabel": "CIF Number:",
"startingChequeNumberLabel": "Starting Cheque Number:",
"endingChequeNumberLabel": "Ending Cheque Number:",
"issueDateLabel": "Issue Date:",
"numberOfChequesLabel": "Number of Cheques:",
"instrumentTypeLabel": "Instrument Type:",
"closeButton": "Close",
"stopSingleChequeTitle": "Stop Single Cheque",
"chequeNumberHint": "Cheque Number *",
"pleaseEnterChequeNumberError": "Please enter a cheque number",
"invalidChequeNumberFormatError": "Invalid cheque number format",
"chequeNumberRangeError": "Cheque number must be between {from} and {to}",
"instrumentTypeHint": "Instrument Type *",
"stopIssueDateHint": "Stop Issue Date",
"stopExpiryDateHint": "Stop Expiry Date",
"stopAmountHint": "Stop Amount",
"stopCommentHint": "Stop Comment",
"chequebookIssueDateHint": "Chequebook Issue Date",
"successStatus": "Success",
"errorStatus": "Error",
"incorrectTpinErrorMessage": "The TPIN you entered is incorrect. Please try again.",
"internalServerError": "Internal Server Error",
"stopChequeButton": "Stop Cheque",
"stopMultipleChequesTitle": "Stop Multiple Cheques",
"fromChequeNumberHint": "From Cheque Number *",
"toChequeNumberHint": "To Cheque Number *"
} }

View File

@@ -417,5 +417,144 @@
"kycdetails": "केवाईसी विवरण", "kycdetails": "केवाईसी विवरण",
"viewall": "सभी देखें", "viewall": "सभी देखें",
"branchlocator": "शाखा लोकेटर", "branchlocator": "शाखा लोकेटर",
"atmlocator": "एटीएम लोकेटर" "atmlocator": "एटीएम लोकेटर",
"limitSetError": "निर्धारित की जाने वाली सीमा {maxAmount} से कम होनी चाहिए।",
"genericError": "त्रुटि: {errorMessage}",
"limitUpdatedSuccess": "सीमा अपडेट हो गई",
"remainingLimitToday": "आज की शेष सीमा",
"branchNameHint": "शाखा का नाम",
"noMatchingBranches": "कोई मेल खाने वाली शाखा नहीं मिली",
"selfPay": "स्वयं भुगतान",
"savingsAccountType": "बचत खाता",
"amountExceedsDailyLimit": "राशि की शेष दैनिक सीमा से अधिक है",
"incorrectTpinError": "कृपया सही टीपिन दर्ज करें",
"insufficientFundsError": "आपके खाते में पर्याप्त शेष राशि नहीं है",
"somethingWentWrongError": "कुछ गलत हो गया",
"currencyINR": "INR",
"remainingDailyLimit": "शेष दैनिक सीमा:",
"searchByNameOrAccount": "नाम या खाता संख्या से खोजें",
"beneficiaryCooldownMessage": "कूलडाउन अवधि के बाद लाभार्थी सक्षम हो जाएगा।",
"notApplicable": "लागू नहीं",
"savingsAccountLabel": "बचत खाता",
"loanAccountLabel": "ऋण खाता",
"termDepositLabel": "सावधि जमा",
"recurringDepositLabel": "आवर्ती जमा",
"currentAccountLabel": "चालू खाता",
"unknownAccountLabel": "अज्ञात खाता",
"selectAccountTitle": "खाता चुनें",
"noOtherAccounts": "कोई अन्य खाता नहीं मिला",
"kccbBankName": "कांगड़ा केंद्रीय सहकारी बैंक",
"fundTransferTitle": "धन हस्तांतरण",
"debitFromLabel": "से डेबिट करें",
"creditToLabel": "को क्रेडिट करें",
"remarksOptionalHint": "टिप्पणी (वैकल्पिक)",
"amountLabel": "राशि",
"amountRequiredError": "राशि आवश्यक है",
"validAmountError": "कृपया एक वैध राशि दर्ज करें",
"fetchingDailyLimitLoader": "दैनिक सीमा लाई जा रही है...",
"proceedButton": "आगे बढ़ें",
"enterKey": "दर्ज करें",
"backKey": "वापस",
"doneKey": "पूर्ण",
"transactionDate": "{date} को",
"paymentResultPng": "/payment_result.png",
"rubikFont": "Rubik",
"transactionDateLabel": "दिनांक: {date}",
"utrLabel": "UTR: {utr}",
"searchByNameOrAccountHint": "नाम या खाता संख्या से खोजें",
"savingsAccountDropdown": "बचत",
"beneficiaryExistsError": "लाभार्थी पहले से मौजूद है",
"somethingWentWrongShort": "कुछ गलत हो गया",
"currentAccountDropdown": "चालू",
"failedToDeleteBeneficiaryError": "लाभार्थी को हटाने में विफल: {error}",
"notAvailable": "उपलब्ध नहीं है",
"bankNameLabel": "बैंक का नाम",
"accountNumberLabel": "खाता संख्या",
"accountTypeLabel": "खाते का प्रकार",
"ifscCodeLabel": "IFSC कोड",
"branchNameLabel": "शाखा का नाम",
"enquiryEmailSubject": "पूछताछ",
"couldNotOpenEmailApp": "{email} के लिए ईमेल ऐप नहीं खोला जा सका",
"couldNotOpenDialer": "{phone} के लिए डायलर नहीं खोला जा सका",
"couldNotLaunchUrl": "{url} लॉन्च नहीं किया जा सका",
"complaintFormUrl": "https://kccbhp.bank.in/complaint-form/",
"complaintFormTitle": "शिकायत प्रपत्र",
"chairmanEmail": "chairman@kccb.in",
"chairmanPhone": "01892-222677",
"mdEmail": "md@kccb.in",
"mdPhone": "01892-224969",
"gmwEmail": "gmw@kccb.in",
"gmwPhone": "01892-223280",
"gmnEmail": "gmn@kccb.in",
"gmnPhone": "01892-224607",
"atmNameAddressHint": "नाम/पता",
"noMatchingAtms": "कोई मेल खाने वाला एटीएम नहीं मिला",
"faq1Question": "मैं मोबाइल बैंकिंग ऐप में कैसे लॉग इन करूं?",
"faq1Answer": "आप अपने ग्राहक नंबर और पासवर्ड का उपयोग करके लॉग इन कर सकते हैं। समर्थित उपकरणों के लिए बायोमेट्रिक लॉगिन (फिंगरप्रिंट) और एमपिन भी उ।",
"faq2Question": "क्या इस ऐप पर मेरी बैंकिंग जानकारी सुरक्षित है?",
"faq2Answer": "हां। हम आपके डेटा को सुरक्षित रखने के लिए उद्योग-मानक एन्क्रिप्शन और बहु-कारक प्रमाणीकरण का उपयोग करते हैं।",
"faq3Question": "मैं अपने खाते की शेष राशि कैसे देख सकता हूं?",
"faq3Answer": "लॉग इन करने के बाद, आपके खाते की शेष राशि होम स्क्रीन पर प्रदर्शित होगी। आप “खाते” अनुभाग के तहत विस्तृत शेष राशि भी देख सकते हैं।",
"faq4Question": "क्या मैं अन्य बैंक खातों में पैसे ट्रांसफर कर सकता हूं?",
"faq4Answer": "हां। आप भारत में किसी भी बैंक खाते में धनराशि स्थानांतरित करने के लिए एनईएफटी, आरटीजीएस या आईएमपीएस का उपयोग कर सकते हैं।",
"faq5Question": "मैं अपना लेनदेन इतिहास कैसे देखूं?",
"faq5Answer": "हाल के और पिछले लेनदेन देखने के लिए होम स्क्रीन के नीचे “खाता विवरण” आइकन पर क्लिक करें।",
"chequeEnquiryTitle": "चेक पूछताछ",
"chequeEnquirySubtitle": "आप अपनी जारी की गई चेक बुक, प्रस्तुत किए गए चेकों और रोके गए चेकों के विवरण देख सकते हैं, जिसमें प्रासंगिक तिथियां, चेक नं्य आवश्यक जानकारी शामिल है",
"stopChequeSubtitle": "अपनी जारी की गई चेकबुक से एक या अधिक चेकों के लिए स्टॉप आरंभ करें। यह आवश्यक सेवा अनधिकृत लेनदेन को रोकने और धोखाधड़ी से बचानद करती है।",
"chequeEnquiryFailedError": "चेक स्थिति लाने में विफल: {error}",
"accountNumberTitle": "खाता संख्या",
"noAccountsFound": "कोई खाता नहीं मिला",
"searchByChequeDetailsHint": "चेक विवरण द्वारा खोजें",
"noChequeStatusFound": "कोई चेक स्थिति नहीं मिली।",
"chequebookIssuedLabel": "चेकबुक जारी (CI)",
"branchCodeLabel": "शाखा कोड:",
"fromChequeLabel": "चेक से:",
"toChequeLabel": "चेक तक:",
"dateLabel": "दिनांक:",
"chequesCountLabel": "चेकों की संख्या:",
"presentedChequeLabel": "प्रस्तुत चेक (PR)",
"chequeNumberLabel": "चेक नंबर:",
"transactionCodeLabel": "लेनदेन कोड:",
"amountLabelWithColon": "राशि:",
"statusLabel": "स्थिति:",
"stopChequeLabel": "चेक रोकें (ST)",
"stopIssueDateLabel": "रोक जारी करने की तारीख:",
"stopExpiryDateLabel": "रोक समाप्ति तिथि:",
"emptyString": "",
"cashCreditAccountLabel": "नकद क्रेडिट खाता",
"stopChequeTitle": "चेक रोकें",
"noChequebookToStop": "से चेक रोकने के लिए कोई चेक बुक नहीं मिली।",
"stopSingleChequeButton": "एकल चेक रोकें",
"pleaseSelectAccountFirst": "कृपया पहले एक खाता चुनें।",
"stopMultipleChequesButton": "एकाधिक चेक रोकें",
"noChequeIssuedStatus": "कोई चेक जारी स्थिति नहीं मिली।",
"chequebookDetailsTitle": "चेकबुक विवरण",
"customerNameLabel": "ग्राहक का नाम:",
"cifNumberLabel": "CIF नंबर:",
"startingChequeNumberLabel": "प्रारंभिक चेक नंबर:",
"endingChequeNumberLabel": "अंतिम चेक नंबर:",
"issueDateLabel": "जारी करने की तारीख:",
"numberOfChequesLabel": "चेकों की संख्या:",
"instrumentTypeLabel": "उपकरण का प्रकार:",
"closeButton": "बंद करें",
"stopSingleChequeTitle": "एकल चेक रोकें",
"chequeNumberHint": "चेक नंबर *",
"pleaseEnterChequeNumberError": "कृपया एक चेक नंबर दर्ज करें",
"invalidChequeNumberFormatError": "अमान्य चेक नंबर प्रारूप",
"chequeNumberRangeError": "चेक नंबर {from} और {to} के बीच होना चाहिए",
"instrumentTypeHint": "उपकरण का प्रकार *",
"stopIssueDateHint": "रोक जारी करने की तारीख",
"stopExpiryDateHint": "रोक समाप्ति तिथि",
"stopAmountHint": "राशि रोकें",
"stopCommentHint": "टिप्पणी रोकें",
"chequebookIssueDateHint": "चेकबुक जारी करने की तारीख",
"successStatus": "सफलता",
"errorStatus": "त्रुटि",
"incorrectTpinErrorMessage": "आपके द्वारा दर्ज किया गया टीपिन गलत है। कृपया पुन: प्रयास करें।",
"internalServerError": "आंतरिक सर्वर त्रुटि",
"stopChequeButton": "चेक रोकें",
"stopMultipleChequesTitle": "एकाधिक चेक रोकें",
"fromChequeNumberHint": "चेक नंबर से *",
"toChequeNumberHint": "चेक नंबर तक *"
} }