Localization Changes #3
This commit is contained in:
@@ -4,7 +4,6 @@ import '../../features/auth/models/auth_token.dart';
|
|||||||
import '../../features/auth/models/auth_credentials.dart';
|
import '../../features/auth/models/auth_credentials.dart';
|
||||||
import '../../core/errors/exceptions.dart';
|
import '../../core/errors/exceptions.dart';
|
||||||
|
|
||||||
|
|
||||||
class AuthService {
|
class AuthService {
|
||||||
final Dio _dio;
|
final Dio _dio;
|
||||||
AuthService(this._dio);
|
AuthService(this._dio);
|
||||||
@@ -15,7 +14,7 @@ class AuthService {
|
|||||||
'/api/auth/login',
|
'/api/auth/login',
|
||||||
data: credentials.toJson(),
|
data: credentials.toJson(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
return AuthToken.fromJson(response.data);
|
return AuthToken.fromJson(response.data);
|
||||||
} else {
|
} else {
|
||||||
@@ -30,7 +29,8 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
throw NetworkException('Network error during login');
|
throw NetworkException('Network error during login');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw UnexpectedException('Unexpected error during login: ${e.toString()}');
|
throw UnexpectedException(
|
||||||
|
'Unexpected error during login: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ class AuthService {
|
|||||||
'/auth/refresh',
|
'/auth/refresh',
|
||||||
data: {'refresh_token': refreshToken},
|
data: {'refresh_token': refreshToken},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
return AuthToken.fromJson(response.data);
|
return AuthToken.fromJson(response.data);
|
||||||
} else {
|
} else {
|
||||||
@@ -54,7 +54,7 @@ class AuthService {
|
|||||||
Future<bool> checkTpin() async {
|
Future<bool> checkTpin() async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.get('/api/auth/tpin');
|
final response = await _dio.get('/api/auth/tpin');
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
return response.data['tpinSet'] as bool;
|
return response.data['tpinSet'] as bool;
|
||||||
} else {
|
} else {
|
||||||
@@ -66,7 +66,8 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
throw NetworkException('Network error during TPIN check');
|
throw NetworkException('Network error during TPIN check');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw UnexpectedException('Unexpected error during TPIN check: ${e.toString()}');
|
throw UnexpectedException(
|
||||||
|
'Unexpected error during TPIN check: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ class AuthService {
|
|||||||
'/api/auth/tpin',
|
'/api/auth/tpin',
|
||||||
data: {'tpin': tpin},
|
data: {'tpin': tpin},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw AuthException('Failed to set TPIN');
|
throw AuthException('Failed to set TPIN');
|
||||||
}
|
}
|
||||||
@@ -86,8 +87,8 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
throw NetworkException('Network error during TPIN setup');
|
throw NetworkException('Network error during TPIN setup');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw UnexpectedException('Unexpected error during TPIN setup: ${e.toString()}');
|
throw UnexpectedException(
|
||||||
|
'Unexpected error during TPIN setup: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
@@ -22,8 +22,8 @@ class ImpsService {
|
|||||||
throw Exception(
|
throw Exception(
|
||||||
'RTGS transaction failed with status code: ${response.statusCode}');
|
'RTGS transaction failed with status code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
} on DioException {
|
} on DioException {
|
||||||
rethrow ;
|
rethrow;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('An unexpected error occurred: ${e.toString()}');
|
throw Exception('An unexpected error occurred: ${e.toString()}');
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,8 @@ class NeftService {
|
|||||||
|
|
||||||
NeftService(this._dio);
|
NeftService(this._dio);
|
||||||
|
|
||||||
Future<NeftResponse> processNeftTransaction(NeftTransaction transaction) async {
|
Future<NeftResponse> processNeftTransaction(
|
||||||
|
NeftTransaction transaction) async {
|
||||||
try {
|
try {
|
||||||
await Future.delayed(const Duration(seconds: 3));
|
await Future.delayed(const Duration(seconds: 3));
|
||||||
final response = await _dio.post(
|
final response = await _dio.post(
|
||||||
|
@@ -10,7 +10,7 @@ class PaymentService {
|
|||||||
Future<PaymentResponse> processQuickPayWithinBank(Transfer transfer) async {
|
Future<PaymentResponse> processQuickPayWithinBank(Transfer transfer) async {
|
||||||
try {
|
try {
|
||||||
await Future.delayed(const Duration(seconds: 3)); // Simulate delay
|
await Future.delayed(const Duration(seconds: 3)); // Simulate delay
|
||||||
|
|
||||||
await _dio.post('/api/payment/transfer', data: transfer.toJson());
|
await _dio.post('/api/payment/transfer', data: transfer.toJson());
|
||||||
|
|
||||||
return PaymentResponse(
|
return PaymentResponse(
|
||||||
|
@@ -22,8 +22,8 @@ class RtgsService {
|
|||||||
throw Exception(
|
throw Exception(
|
||||||
'RTGS transaction failed with status code: ${response.statusCode}');
|
'RTGS transaction failed with status code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
} on DioException {
|
} on DioException {
|
||||||
rethrow ;
|
rethrow;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('An unexpected error occurred: ${e.toString()}');
|
throw Exception('An unexpected error occurred: ${e.toString()}');
|
||||||
}
|
}
|
||||||
|
@@ -28,4 +28,4 @@ class UserService {
|
|||||||
throw Exception('Unexpected error: ${e.toString()}');
|
throw Exception('Unexpected error: ${e.toString()}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ import '../features/dashboard/screens/dashboard_screen.dart';
|
|||||||
class AppRoutes {
|
class AppRoutes {
|
||||||
// Private constructor to prevent instantiation
|
// Private constructor to prevent instantiation
|
||||||
AppRoutes._();
|
AppRoutes._();
|
||||||
|
|
||||||
// Route names
|
// Route names
|
||||||
static const String splash = '/';
|
static const String splash = '/';
|
||||||
static const String login = '/login';
|
static const String login = '/login';
|
||||||
@@ -25,7 +25,7 @@ class AppRoutes {
|
|||||||
static const String accounts = '/accounts';
|
static const String accounts = '/accounts';
|
||||||
static const String transactions = '/transactions';
|
static const String transactions = '/transactions';
|
||||||
static const String payments = '/payments';
|
static const String payments = '/payments';
|
||||||
|
|
||||||
// Route generator
|
// Route generator
|
||||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
@@ -35,13 +35,16 @@ class AppRoutes {
|
|||||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||||
|
|
||||||
case mPin:
|
case mPin:
|
||||||
return MaterialPageRoute(builder: (_) => const MPinScreen(mode: MPinMode.enter,));
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const MPinScreen(
|
||||||
|
mode: MPinMode.enter,
|
||||||
|
));
|
||||||
|
|
||||||
case register:
|
case register:
|
||||||
// Placeholder - create the RegisterScreen class and uncomment
|
// Placeholder - create the RegisterScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const RegisterScreen());
|
// return MaterialPageRoute(builder: (_) => const RegisterScreen());
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
|
|
||||||
case forgotPassword:
|
case forgotPassword:
|
||||||
// Placeholder - create the ForgotPasswordScreen class and uncomment
|
// Placeholder - create the ForgotPasswordScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const ForgotPasswordScreen());
|
// return MaterialPageRoute(builder: (_) => const ForgotPasswordScreen());
|
||||||
@@ -49,31 +52,30 @@ class AppRoutes {
|
|||||||
|
|
||||||
case navigationScaffold:
|
case navigationScaffold:
|
||||||
return MaterialPageRoute(builder: (_) => const NavigationScaffold());
|
return MaterialPageRoute(builder: (_) => const NavigationScaffold());
|
||||||
|
|
||||||
case dashboard:
|
case dashboard:
|
||||||
return MaterialPageRoute(builder: (_) => const DashboardScreen());
|
return MaterialPageRoute(builder: (_) => const DashboardScreen());
|
||||||
|
|
||||||
case accounts:
|
case accounts:
|
||||||
// Placeholder - create the AccountsScreen class and uncomment
|
// Placeholder - create the AccountsScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const AccountsScreen());
|
// return MaterialPageRoute(builder: (_) => const AccountsScreen());
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
|
|
||||||
case transactions:
|
case transactions:
|
||||||
// Placeholder - create the TransactionsScreen class and uncomment
|
// Placeholder - create the TransactionsScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const TransactionsScreen());
|
// return MaterialPageRoute(builder: (_) => const TransactionsScreen());
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
|
|
||||||
case payments:
|
case payments:
|
||||||
// Placeholder - create the PaymentsScreen class and uncomment
|
// Placeholder - create the PaymentsScreen class and uncomment
|
||||||
// return MaterialPageRoute(builder: (_) => const PaymentsScreen());
|
// return MaterialPageRoute(builder: (_) => const PaymentsScreen());
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error route
|
// Error route
|
||||||
static Route<dynamic> _errorRoute() {
|
static Route<dynamic> _errorRoute() {
|
||||||
return MaterialPageRoute(builder: (_) {
|
return MaterialPageRoute(builder: (_) {
|
||||||
@@ -87,4 +89,4 @@ class AppRoutes {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
enum ThemeType {
|
enum ThemeType {
|
||||||
violet,
|
violet,
|
||||||
green,
|
green,
|
||||||
orange,
|
orange,
|
||||||
blue,
|
blue,
|
||||||
}
|
}
|
||||||
|
@@ -30,4 +30,3 @@ class AppThemes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
class AppException implements Exception {
|
class AppException implements Exception {
|
||||||
final String message;
|
final String message;
|
||||||
|
|
||||||
AppException(this.message);
|
AppException(this.message);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => message;
|
String toString() => message;
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ class NetworkException extends AppException {
|
|||||||
NetworkException(super.message);
|
NetworkException(super.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthException implements Exception{
|
class AuthException implements Exception {
|
||||||
final String message;
|
final String message;
|
||||||
AuthException(this.message);
|
AuthException(this.message);
|
||||||
|
|
||||||
@@ -21,4 +21,4 @@ class AuthException implements Exception{
|
|||||||
|
|
||||||
class UnexpectedException extends AppException {
|
class UnexpectedException extends AppException {
|
||||||
UnexpectedException(super.message);
|
UnexpectedException(super.message);
|
||||||
}
|
}
|
||||||
|
@@ -62,4 +62,3 @@ class Beneficiary {
|
|||||||
return 'Beneficiary(accountNo: $accountNo, accountType: $accountType, ifscCode: $ifscCode, name: $name)';
|
return 'Beneficiary(accountNo: $accountNo, accountType: $accountType, ifscCode: $ifscCode, name: $name)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,4 +30,3 @@ class Ifsc {
|
|||||||
return 'IFSC(ifscCode: $ifscCode, bankName: $bankName, branchName: $branchName)';
|
return 'IFSC(ifscCode: $ifscCode, bankName: $bankName, branchName: $branchName)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ class TransferResponse {
|
|||||||
TransferResponse({
|
TransferResponse({
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.message,
|
required this.message,
|
||||||
required this.error,
|
required this.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory TransferResponse.fromJson(Map<String, dynamic> json) {
|
factory TransferResponse.fromJson(Map<String, dynamic> json) {
|
||||||
@@ -42,4 +42,4 @@ class TransferResponse {
|
|||||||
error: json['error'] as String?,
|
error: json['error'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ class AuthRepository {
|
|||||||
final AuthService _authService;
|
final AuthService _authService;
|
||||||
final UserService _userService;
|
final UserService _userService;
|
||||||
final SecureStorage _secureStorage;
|
final SecureStorage _secureStorage;
|
||||||
|
|
||||||
static const _accessTokenKey = 'access_token';
|
static const _accessTokenKey = 'access_token';
|
||||||
static const _tokenExpiryKey = 'token_expiry';
|
static const _tokenExpiryKey = 'token_expiry';
|
||||||
|
|
||||||
@@ -18,35 +18,37 @@ class AuthRepository {
|
|||||||
|
|
||||||
Future<List<User>> login(String customerNo, String password) async {
|
Future<List<User>> login(String customerNo, String password) async {
|
||||||
// Create credentials and call service
|
// Create credentials and call service
|
||||||
final credentials = AuthCredentials(customerNo: customerNo, password: password);
|
final credentials =
|
||||||
|
AuthCredentials(customerNo: customerNo, password: password);
|
||||||
final authToken = await _authService.login(credentials);
|
final authToken = await _authService.login(credentials);
|
||||||
|
|
||||||
// Save token securely
|
// Save token securely
|
||||||
await _saveAuthToken(authToken);
|
await _saveAuthToken(authToken);
|
||||||
|
|
||||||
// Get and save user profile
|
// Get and save user profile
|
||||||
final users = await _userService.getUserDetails();
|
final users = await _userService.getUserDetails();
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isLoggedIn() async {
|
Future<bool> isLoggedIn() async {
|
||||||
final token = await _getAuthToken();
|
final token = await _getAuthToken();
|
||||||
return token != null && !token.isExpired;
|
return token != null && !token.isExpired;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getAccessToken() async {
|
Future<String?> getAccessToken() async {
|
||||||
final token = await _getAuthToken();
|
final token = await _getAuthToken();
|
||||||
if (token == null) return null;
|
if (token == null) return null;
|
||||||
|
|
||||||
return token.accessToken;
|
return token.accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private helper methods
|
// Private helper methods
|
||||||
Future<void> _saveAuthToken(AuthToken token) async {
|
Future<void> _saveAuthToken(AuthToken token) async {
|
||||||
await _secureStorage.write(_accessTokenKey, token.accessToken);
|
await _secureStorage.write(_accessTokenKey, token.accessToken);
|
||||||
await _secureStorage.write(_tokenExpiryKey, token.expiresAt.toIso8601String());
|
await _secureStorage.write(
|
||||||
|
_tokenExpiryKey, token.expiresAt.toIso8601String());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AuthToken?> _getAuthToken() async {
|
Future<AuthToken?> _getAuthToken() async {
|
||||||
final accessToken = await _secureStorage.read(_accessTokenKey);
|
final accessToken = await _secureStorage.read(_accessTokenKey);
|
||||||
final expiryString = await _secureStorage.read(_tokenExpiryKey);
|
final expiryString = await _secureStorage.read(_tokenExpiryKey);
|
||||||
@@ -59,4 +61,4 @@ class AuthRepository {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import 'package:kmobile/data/models/transfer.dart';
|
import 'package:kmobile/data/models/transfer.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
|
||||||
abstract class TransferRepository {
|
abstract class TransferRepository {
|
||||||
Future<TransferResponse> transfer(Transfer transfer);
|
Future<TransferResponse> transfer(Transfer transfer);
|
||||||
}
|
}
|
||||||
@@ -25,4 +24,4 @@ class TransferRepositoryImpl implements TransferRepository {
|
|||||||
|
|
||||||
return TransferResponse.fromJson(resp.data as Map<String, dynamic>);
|
return TransferResponse.fromJson(resp.data as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,7 @@ Dio _createDioClient() {
|
|||||||
BaseOptions(
|
BaseOptions(
|
||||||
baseUrl:
|
baseUrl:
|
||||||
'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080',
|
'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080',
|
||||||
//'http://localhost:8081',
|
//'http://localhost:8081',
|
||||||
connectTimeout: const Duration(seconds: 5),
|
connectTimeout: const Duration(seconds: 5),
|
||||||
receiveTimeout: const Duration(seconds: 10),
|
receiveTimeout: const Duration(seconds: 10),
|
||||||
headers: {
|
headers: {
|
||||||
|
@@ -4,7 +4,7 @@ class Account {
|
|||||||
final String accountType;
|
final String accountType;
|
||||||
final double balance;
|
final double balance;
|
||||||
final String currency;
|
final String currency;
|
||||||
|
|
||||||
Account({
|
Account({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.accountNumber,
|
required this.accountNumber,
|
||||||
@@ -12,4 +12,4 @@ class Account {
|
|||||||
required this.balance,
|
required this.balance,
|
||||||
required this.currency,
|
required this.currency,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ class _AccountInfoScreen extends State<AccountInfoScreen> {
|
|||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
|
|
||||||
InfoRow(
|
InfoRow(
|
||||||
title: AppLocalizations.of(context).customerNumber,
|
title: AppLocalizations.of(context).customerNumber,
|
||||||
value: selectedUser.cifNumber ?? 'N/A',
|
value: selectedUser.cifNumber ?? 'N/A',
|
||||||
|
@@ -294,10 +294,10 @@ class _AccountStatementScreen extends State<AccountStatementScreen> {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) =>
|
builder: (_) => TransactionDetailsScreen(
|
||||||
TransactionDetailsScreen(transaction: tx),
|
transaction: tx),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@@ -3,7 +3,7 @@ import 'package:kmobile/l10n/app_localizations.dart';
|
|||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
|
||||||
class TransactionDetailsScreen extends StatelessWidget {
|
class TransactionDetailsScreen extends StatelessWidget {
|
||||||
final dynamic transaction;
|
final dynamic transaction;
|
||||||
|
|
||||||
const TransactionDetailsScreen({super.key, required this.transaction});
|
const TransactionDetailsScreen({super.key, required this.transaction});
|
||||||
|
|
||||||
@@ -22,29 +22,30 @@ class TransactionDetailsScreen extends StatelessWidget {
|
|||||||
// final file = await File('${tempDir.path}/payment_result.png').create();
|
// final file = await File('${tempDir.path}/payment_result.png').create();
|
||||||
// await file.writeAsBytes(pngBytes);
|
// await file.writeAsBytes(pngBytes);
|
||||||
|
|
||||||
// await Share.shareXFiles(
|
// await Share.shareXFiles(
|
||||||
// [XFile(file.path)],
|
// [XFile(file.path)],
|
||||||
// text: AppLocalizations.of(context).paymentResult,
|
// text: AppLocalizations.of(context).paymentResult,
|
||||||
// );
|
// );
|
||||||
// } catch (e) {
|
// } catch (e) {
|
||||||
// if (!mounted) return;
|
// if (!mounted) return;
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
// SnackBar(
|
// SnackBar(
|
||||||
// content: Text(
|
// content: Text(
|
||||||
// '${AppLocalizations.of(context).failedToShareScreenshot}: $e',
|
// '${AppLocalizations.of(context).failedToShareScreenshot}: $e',
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text(AppLocalizations.of(context).transactionDetails)),
|
appBar:
|
||||||
|
AppBar(title: Text(AppLocalizations.of(context).transactionDetails)),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Absolute center for amount + icon + date + details
|
// Absolute center for amount + icon + date + details
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -93,39 +94,45 @@ class TransactionDetailsScreen extends StatelessWidget {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
// ignore: unnecessary_cast
|
// ignore: unnecessary_cast
|
||||||
_buildDetailRow(AppLocalizations.of(context).transactionType as String, transaction.type ?? ""),
|
_buildDetailRow(
|
||||||
_buildDetailRow(AppLocalizations.of(context).transferType, transaction.name.split("/").first ?? ""),
|
AppLocalizations.of(context).transactionType as String,
|
||||||
if(transaction.name.length> 12) ... [
|
transaction.type ?? ""),
|
||||||
_buildDetailRow(AppLocalizations.of(context).utrNo, transaction.name.split("= ")[1].split(" ")[0] ?? ""),
|
_buildDetailRow(AppLocalizations.of(context).transferType,
|
||||||
_buildDetailRow(AppLocalizations.of(context).beneficiaryAccountNo, transaction.name.split("A/C ").last ?? "")
|
transaction.name.split("/").first ?? ""),
|
||||||
|
if (transaction.name.length > 12) ...[
|
||||||
|
_buildDetailRow(AppLocalizations.of(context).utrNo,
|
||||||
|
transaction.name.split("= ")[1].split(" ")[0] ?? ""),
|
||||||
|
_buildDetailRow(
|
||||||
|
AppLocalizations.of(context).beneficiaryAccountNo,
|
||||||
|
transaction.name.split("A/C ").last ?? "")
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// ElevatedButton.icon(
|
// ElevatedButton.icon(
|
||||||
// onPressed: _shareScreenshot,
|
// onPressed: _shareScreenshot,
|
||||||
// icon: Icon(
|
// icon: Icon(
|
||||||
// Icons.share_rounded,
|
// Icons.share_rounded,
|
||||||
// color: Theme.of(context).primaryColor,
|
// color: Theme.of(context).primaryColor,
|
||||||
// ),
|
// ),
|
||||||
// label: Text(
|
// label: Text(
|
||||||
// AppLocalizations.of(context).share,
|
// AppLocalizations.of(context).share,
|
||||||
// style: TextStyle(color: Theme.of(context).primaryColor),
|
// style: TextStyle(color: Theme.of(context).primaryColor),
|
||||||
// ),
|
// ),
|
||||||
// style: ElevatedButton.styleFrom(
|
// style: ElevatedButton.styleFrom(
|
||||||
// backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
// backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
|
// padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
|
||||||
// shape: RoundedRectangleBorder(
|
// shape: RoundedRectangleBorder(
|
||||||
// side: BorderSide(color: Theme.of(context).primaryColor, width: 1),
|
// side: BorderSide(color: Theme.of(context).primaryColor, width: 1),
|
||||||
// borderRadius: BorderRadius.circular(30),
|
// borderRadius: BorderRadius.circular(30),
|
||||||
// ),
|
// ),
|
||||||
// textStyle: const TextStyle(
|
// textStyle: const TextStyle(
|
||||||
// fontSize: 18,
|
// fontSize: 18,
|
||||||
// fontWeight: FontWeight.w600,
|
// fontWeight: FontWeight.w600,
|
||||||
// color: Colors.black,
|
// color: Colors.black,
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -15,4 +15,3 @@ class ThemeState extends Equatable {
|
|||||||
@override
|
@override
|
||||||
List<Object?> get props => [themeType];
|
List<Object?> get props => [themeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,12 +6,12 @@ import 'package:equatable/equatable.dart';
|
|||||||
class AuthToken extends Equatable {
|
class AuthToken extends Equatable {
|
||||||
final String accessToken;
|
final String accessToken;
|
||||||
final DateTime expiresAt;
|
final DateTime expiresAt;
|
||||||
|
|
||||||
const AuthToken({
|
const AuthToken({
|
||||||
required this.accessToken,
|
required this.accessToken,
|
||||||
required this.expiresAt,
|
required this.expiresAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory AuthToken.fromJson(Map<String, dynamic> json) {
|
factory AuthToken.fromJson(Map<String, dynamic> json) {
|
||||||
return AuthToken(
|
return AuthToken(
|
||||||
accessToken: json['token'],
|
accessToken: json['token'],
|
||||||
@@ -29,7 +29,8 @@ class AuthToken extends Equatable {
|
|||||||
// Pad the payload if necessary
|
// Pad the payload if necessary
|
||||||
String normalized = base64Url.normalize(payload);
|
String normalized = base64Url.normalize(payload);
|
||||||
final payloadMap = json.decode(utf8.decode(base64Url.decode(normalized)));
|
final payloadMap = json.decode(utf8.decode(base64Url.decode(normalized)));
|
||||||
if (payloadMap is! Map<String, dynamic> || !payloadMap.containsKey('exp')) {
|
if (payloadMap is! Map<String, dynamic> ||
|
||||||
|
!payloadMap.containsKey('exp')) {
|
||||||
throw Exception('Invalid payload');
|
throw Exception('Invalid payload');
|
||||||
}
|
}
|
||||||
final exp = payloadMap['exp'];
|
final exp = payloadMap['exp'];
|
||||||
@@ -40,9 +41,9 @@ class AuthToken extends Equatable {
|
|||||||
return DateTime.now().add(const Duration(hours: 1));
|
return DateTime.now().add(const Duration(hours: 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isExpired => DateTime.now().isAfter(expiresAt);
|
bool get isExpired => DateTime.now().isAfter(expiresAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [accessToken, expiresAt];
|
List<Object> get props => [accessToken, expiresAt];
|
||||||
}
|
}
|
||||||
|
@@ -48,9 +48,9 @@ class LoginScreenState extends State<LoginScreen>
|
|||||||
void _submitForm() {
|
void _submitForm() {
|
||||||
if (_formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
context.read<AuthCubit>().login(
|
context.read<AuthCubit>().login(
|
||||||
_customerNumberController.text.trim(),
|
_customerNumberController.text.trim(),
|
||||||
_passwordController.text,
|
_passwordController.text,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,8 @@ class LoginScreenState extends State<LoginScreen>
|
|||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
shape: const StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
foregroundColor: Theme.of(context).primaryColorDark,
|
foregroundColor: Theme.of(context).primaryColorDark,
|
||||||
side: const BorderSide(color: Colors.black, width: 1),
|
side: const BorderSide(color: Colors.black, width: 1),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
@@ -198,7 +198,9 @@ class _MPinScreenState extends State<MPinScreen> {
|
|||||||
key == '<' ? '⌫' : key,
|
key == '<' ? '⌫' : key,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: key == 'Enter' ? Theme.of(context).primaryColor : Colors.black,
|
color: key == 'Enter'
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -19,11 +19,8 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
|
|||||||
|
|
||||||
// Automatically go to logizn after 4 seconds
|
// Automatically go to logizn after 4 seconds
|
||||||
Timer(const Duration(seconds: 4), () {
|
Timer(const Duration(seconds: 4), () {
|
||||||
|
|
||||||
widget.onContinue();
|
widget.onContinue();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -73,7 +70,8 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator(color: Theme.of(context).scaffoldBackgroundColor),
|
child: CircularProgressIndicator(
|
||||||
|
color: Theme.of(context).scaffoldBackgroundColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@@ -170,14 +170,16 @@ class _AddBeneficiaryScreen extends State<AddBeneficiaryScreen> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final isSuccess = await service.sendForValidation(beneficiaryWithTpin);
|
final isSuccess =
|
||||||
|
await service.sendForValidation(beneficiaryWithTpin);
|
||||||
|
|
||||||
if (pinScreenContext.mounted) {
|
if (pinScreenContext.mounted) {
|
||||||
Navigator.pop(pinScreenContext); // Close the spinner
|
Navigator.pop(pinScreenContext); // Close the spinner
|
||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
pinScreenContext,
|
pinScreenContext,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (ctx) => BeneficiaryResultPage(isSuccess: isSuccess),
|
builder: (ctx) =>
|
||||||
|
BeneficiaryResultPage(isSuccess: isSuccess),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,8 @@ class _AddBeneficiaryScreen extends State<AddBeneficiaryScreen> {
|
|||||||
Navigator.pop(pinScreenContext); // Close the spinner
|
Navigator.pop(pinScreenContext); // Close the spinner
|
||||||
ScaffoldMessenger.of(pinScreenContext).showSnackBar(
|
ScaffoldMessenger.of(pinScreenContext).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(AppLocalizations.of(context).somethingWentWrong)),
|
content: Text(
|
||||||
|
AppLocalizations.of(context).somethingWentWrong)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +458,8 @@ class _AddBeneficiaryScreen extends State<AddBeneficiaryScreen> {
|
|||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
strokeWidth: 2),
|
strokeWidth: 2),
|
||||||
)
|
)
|
||||||
: Text(AppLocalizations.of(context).validateBeneficiary),
|
: Text(AppLocalizations.of(context)
|
||||||
|
.validateBeneficiary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -66,34 +66,35 @@ class _BeneficiaryResultPageState extends State<BeneficiaryResultPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 20, // keep it slightly above the very bottom
|
bottom: 20, // keep it slightly above the very bottom
|
||||||
left: 16,
|
left: 16,
|
||||||
right: 16,
|
right: 16,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 56, // larger button height
|
height: 56, // larger button height
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pushReplacement( // ensures back goes to ScaffoldScreen
|
Navigator.pushReplacement(
|
||||||
context,
|
// ensures back goes to ScaffoldScreen
|
||||||
MaterialPageRoute(
|
context,
|
||||||
builder: (context) => const NavigationScaffold(),
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const NavigationScaffold(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const StadiumBorder(),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
backgroundColor: Theme.of(context).primaryColorDark,
|
||||||
|
foregroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
AppLocalizations.of(context).done,
|
||||||
|
style: const TextStyle(fontSize: 18), // slightly bigger text
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
shape: const StadiumBorder(),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
||||||
backgroundColor: Theme.of(context).primaryColorDark,
|
|
||||||
foregroundColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
AppLocalizations.of(context).done,
|
|
||||||
style: const TextStyle(fontSize: 18), // slightly bigger text
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.isSuccess)
|
if (widget.isSuccess)
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
@@ -112,4 +113,4 @@ Positioned(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -67,29 +67,30 @@ class _ManageBeneficiariesScreen extends State<ManageBeneficiariesScreen> {
|
|||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('kangra central')) {
|
if (bankName != null && bankName.toLowerCase().contains('kangra central')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/icon.png',
|
'assets/images/icon.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('hdfc bank ltd')) {
|
if (bankName != null && bankName.toLowerCase().contains('hdfc bank ltd')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/hdfc_logo.png',
|
'assets/images/hdfc_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('icici bank ltd')) {
|
if (bankName != null && bankName.toLowerCase().contains('icici bank ltd')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/icici_logo.png',
|
'assets/images/icici_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('punjab national bank')) {
|
if (bankName != null &&
|
||||||
|
bankName.toLowerCase().contains('punjab national bank')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/pnb_logo.png',
|
'assets/images/pnb_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
|
@@ -20,7 +20,8 @@ class _CardManagementScreen extends State<CardManagementScreen> {
|
|||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).cardManagement,
|
AppLocalizations.of(context).cardManagement,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
|
@@ -54,7 +54,8 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).cardDetails,
|
AppLocalizations.of(context).cardDetails,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
@@ -189,7 +190,8 @@ class _CardPinChangeDetailsScreen extends State<CardPinChangeDetailsScreen> {
|
|||||||
shape: const StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
foregroundColor: Theme.of(context).scaffoldBackgroundColor,
|
foregroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
),
|
),
|
||||||
child: Text(AppLocalizations.of(context).next),
|
child: Text(AppLocalizations.of(context).next),
|
||||||
),
|
),
|
||||||
|
@@ -54,7 +54,8 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).cardPin,
|
AppLocalizations.of(context).cardPin,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
@@ -144,7 +145,8 @@ class _CardPinSetScreen extends State<CardPinSetScreen> {
|
|||||||
shape: const StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
foregroundColor: Theme.of(context).scaffoldBackgroundColor,
|
foregroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
),
|
),
|
||||||
child: Text(AppLocalizations.of(context).submit),
|
child: Text(AppLocalizations.of(context).submit),
|
||||||
),
|
),
|
||||||
|
@@ -24,7 +24,8 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).chequeManagement,
|
AppLocalizations.of(context).chequeManagement,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
|
@@ -26,7 +26,8 @@ class _CustomerInfoScreenState extends State<CustomerInfoScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).kMobile,
|
AppLocalizations.of(context).kMobile,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
Padding(
|
Padding(
|
||||||
@@ -89,8 +90,7 @@ class _CustomerInfoScreenState extends State<CustomerInfoScreen> {
|
|||||||
),
|
),
|
||||||
InfoField(
|
InfoField(
|
||||||
label: AppLocalizations.of(context).dateOfBirth,
|
label: AppLocalizations.of(context).dateOfBirth,
|
||||||
value:
|
value: (user.dateOfBirth != null &&
|
||||||
(user.dateOfBirth != null &&
|
|
||||||
user.dateOfBirth!.length == 8)
|
user.dateOfBirth!.length == 8)
|
||||||
? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}'
|
? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}'
|
||||||
: 'N/A',
|
: 'N/A',
|
||||||
|
@@ -493,7 +493,13 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
FundTransferBeneficiaryScreen(creditAccountNo: users[selectedAccountIndex].accountNo!, remitterName: users[selectedAccountIndex].name!)));
|
FundTransferBeneficiaryScreen(
|
||||||
|
creditAccountNo:
|
||||||
|
users[selectedAccountIndex]
|
||||||
|
.accountNo!,
|
||||||
|
remitterName:
|
||||||
|
users[selectedAccountIndex]
|
||||||
|
.name!)));
|
||||||
}, disable: false),
|
}, disable: false),
|
||||||
_buildQuickLink(
|
_buildQuickLink(
|
||||||
Symbols.server_person,
|
Symbols.server_person,
|
||||||
@@ -582,14 +588,14 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
style: const TextStyle(fontSize: 16),
|
style: const TextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) =>
|
builder: (_) =>
|
||||||
TransactionDetailsScreen(transaction: tx),
|
TransactionDetailsScreen(transaction: tx),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
@@ -4,7 +4,7 @@ import '../../transactions/models/transaction.dart';
|
|||||||
|
|
||||||
class TransactionListItem extends StatelessWidget {
|
class TransactionListItem extends StatelessWidget {
|
||||||
final Transaction transaction;
|
final Transaction transaction;
|
||||||
|
|
||||||
const TransactionListItem({
|
const TransactionListItem({
|
||||||
super.key,
|
super.key,
|
||||||
required this.transaction,
|
required this.transaction,
|
||||||
@@ -13,7 +13,7 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bool isIncome = transaction.amount > 0;
|
final bool isIncome = transaction.amount > 0;
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
@@ -25,7 +25,8 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _getCategoryColor(transaction.category).withAlpha((0.1 * 255).toInt()),
|
color: _getCategoryColor(transaction.category)
|
||||||
|
.withAlpha((0.1 * 255).toInt()),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
@@ -34,7 +35,7 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
|
|
||||||
// Transaction details
|
// Transaction details
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -48,7 +49,8 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
DateFormat('MMM dd, yyyy • h:mm a').format(transaction.date),
|
DateFormat('MMM dd, yyyy • h:mm a')
|
||||||
|
.format(transaction.date),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.grey[600],
|
color: Colors.grey[600],
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -57,7 +59,7 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Amount
|
// Amount
|
||||||
Text(
|
Text(
|
||||||
'${isIncome ? '+' : ''}${transaction.amount.toStringAsFixed(2)} USD',
|
'${isIncome ? '+' : ''}${transaction.amount.toStringAsFixed(2)} USD',
|
||||||
@@ -106,4 +108,4 @@ class TransactionListItem extends StatelessWidget {
|
|||||||
return Icons.category;
|
return Icons.category;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,12 +40,15 @@ class _EnquiryScreen extends State<EnquiryScreen> {
|
|||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () => _launchEmailAddress(email),
|
onTap: () => _launchEmailAddress(email),
|
||||||
child: Text(email, style: TextStyle(color: Theme.of(context).primaryColor)),
|
child: Text(email,
|
||||||
|
style: TextStyle(color: Theme.of(context).primaryColor)),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () => _launchPhoneNumber(phone),
|
onTap: () => _launchPhoneNumber(phone),
|
||||||
child: Text(phone, style: TextStyle(color: Theme.of(context).scaffoldBackgroundColor)),
|
child: Text(phone,
|
||||||
|
style:
|
||||||
|
TextStyle(color: Theme.of(context).scaffoldBackgroundColor)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -63,7 +66,8 @@ class _EnquiryScreen extends State<EnquiryScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).enquiry,
|
AppLocalizations.of(context).enquiry,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
|
@@ -45,7 +45,8 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _getBankLogo(String? bankName) {
|
Widget _getBankLogo(String? bankName) {
|
||||||
if (bankName != null && bankName.toLowerCase().contains('state bank of india')) {
|
if (bankName != null &&
|
||||||
|
bankName.toLowerCase().contains('state bank of india')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/sbi_logo.png',
|
'assets/images/sbi_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
@@ -69,8 +70,7 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (ctx) => AlertDialog(
|
builder: (ctx) => AlertDialog(
|
||||||
title: Text(AppLocalizations.of(context).invalidRtgs),
|
title: Text(AppLocalizations.of(context).invalidRtgs),
|
||||||
content: Text(
|
content: Text(AppLocalizations.of(context).invalidRtgsPopUp),
|
||||||
AppLocalizations.of(context).invalidRtgsPopUp),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.of(ctx).pop(),
|
onPressed: () => Navigator.of(ctx).pop(),
|
||||||
@@ -120,18 +120,20 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
utr: neftResponse.utr,
|
utr: neftResponse.utr,
|
||||||
);
|
);
|
||||||
completer.complete(paymentResponse);
|
completer.complete(paymentResponse);
|
||||||
} on DioException catch(e) {
|
} on DioException catch (e) {
|
||||||
print('dio exception');
|
print('dio exception');
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
|
||||||
final error = jsonDecode(e.response.toString())['error'];
|
final error = jsonDecode(e.response.toString())['error'];
|
||||||
var errorMessage =
|
var errorMessage = {
|
||||||
{
|
"INCORRECT_TPIN":
|
||||||
"INCORRECT_TPIN" : AppLocalizations.of(context).correctTpin,
|
AppLocalizations.of(context).correctTpin,
|
||||||
"INSUFFICIENT_FUNDS": AppLocalizations.of(context).insufficientFund
|
"INSUFFICIENT_FUNDS":
|
||||||
}[error] ?? AppLocalizations.of(context).somethingWentWrong;
|
AppLocalizations.of(context).insufficientFund
|
||||||
|
}[error] ??
|
||||||
final paymentResponse = PaymentResponse(
|
AppLocalizations.of(context).somethingWentWrong;
|
||||||
|
|
||||||
|
final paymentResponse = PaymentResponse(
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
errorMessage: errorMessage,
|
errorMessage: errorMessage,
|
||||||
);
|
);
|
||||||
@@ -141,7 +143,8 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
print(e.toString());
|
print(e.toString());
|
||||||
final paymentResponse = PaymentResponse(
|
final paymentResponse = PaymentResponse(
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
errorMessage: AppLocalizations.of(context).somethingWentWrong,
|
errorMessage:
|
||||||
|
AppLocalizations.of(context).somethingWentWrong,
|
||||||
);
|
);
|
||||||
completer.complete(paymentResponse);
|
completer.complete(paymentResponse);
|
||||||
}
|
}
|
||||||
@@ -181,14 +184,14 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
// } on DioException catch(e) {
|
// } on DioException catch(e) {
|
||||||
// print('dio exception');
|
// print('dio exception');
|
||||||
// print(e.toString());
|
// print(e.toString());
|
||||||
|
|
||||||
// final error = jsonDecode(e.response.toString())['error'];
|
// final error = jsonDecode(e.response.toString())['error'];
|
||||||
// var errorMessage =
|
// var errorMessage =
|
||||||
// {
|
// {
|
||||||
// "INCORRECT_TPIN" : "Please Enter the correct TPIN",
|
// "INCORRECT_TPIN" : "Please Enter the correct TPIN",
|
||||||
// "INSUFFICIENT_FUNDS": "Your account does not have sufficient balance"
|
// "INSUFFICIENT_FUNDS": "Your account does not have sufficient balance"
|
||||||
// }[error] ?? "Something Went Wrong";
|
// }[error] ?? "Something Went Wrong";
|
||||||
|
|
||||||
// final paymentResponse = PaymentResponse(
|
// final paymentResponse = PaymentResponse(
|
||||||
// isSuccess: false,
|
// isSuccess: false,
|
||||||
// errorMessage: errorMessage,
|
// errorMessage: errorMessage,
|
||||||
@@ -236,19 +239,21 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
utr: rtgsResponse.utr,
|
utr: rtgsResponse.utr,
|
||||||
);
|
);
|
||||||
completer.complete(paymentResponse);
|
completer.complete(paymentResponse);
|
||||||
} on DioException catch(e) {
|
} on DioException catch (e) {
|
||||||
print('dio exception');
|
print('dio exception');
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
|
||||||
final error = jsonDecode(e.response.toString())['error'];
|
final error = jsonDecode(e.response.toString())['error'];
|
||||||
var errorMessage =
|
var errorMessage = {
|
||||||
{
|
"INCORRECT_TPIN":
|
||||||
"INCORRECT_TPIN" : AppLocalizations.of(context).correctTpin,
|
AppLocalizations.of(context).correctTpin,
|
||||||
"INSUFFICIENT_FUNDS": AppLocalizations.of(context).insufficientFund
|
"INSUFFICIENT_FUNDS":
|
||||||
// ignore: use_build_context_synchronously
|
AppLocalizations.of(context).insufficientFund
|
||||||
}[error] ?? AppLocalizations.of(context).somethingWentWrong;
|
// ignore: use_build_context_synchronously
|
||||||
|
}[error] ??
|
||||||
final paymentResponse = PaymentResponse(
|
AppLocalizations.of(context).somethingWentWrong;
|
||||||
|
|
||||||
|
final paymentResponse = PaymentResponse(
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
errorMessage: errorMessage,
|
errorMessage: errorMessage,
|
||||||
);
|
);
|
||||||
@@ -258,7 +263,8 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
print(e.toString());
|
print(e.toString());
|
||||||
final paymentResponse = PaymentResponse(
|
final paymentResponse = PaymentResponse(
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
errorMessage: AppLocalizations.of(context).somethingWentWrong,
|
errorMessage:
|
||||||
|
AppLocalizations.of(context).somethingWentWrong,
|
||||||
);
|
);
|
||||||
completer.complete(paymentResponse);
|
completer.complete(paymentResponse);
|
||||||
}
|
}
|
||||||
@@ -349,14 +355,17 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
|||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
selectedBorderColor: Colors.transparent,
|
selectedBorderColor: Colors.transparent,
|
||||||
splashColor: Theme.of(context).primaryColor.withOpacity(0.1),
|
splashColor: Theme.of(context).primaryColor.withOpacity(0.1),
|
||||||
highlightColor: Theme.of(context).primaryColor.withOpacity(0.05),
|
highlightColor:
|
||||||
|
Theme.of(context).primaryColor.withOpacity(0.05),
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24.0, vertical: 12.0),
|
||||||
child: Text(AppLocalizations.of(context).neft),
|
child: Text(AppLocalizations.of(context).neft),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24.0, vertical: 12.0),
|
||||||
child: Text(AppLocalizations.of(context).rtgs),
|
child: Text(AppLocalizations.of(context).rtgs),
|
||||||
),
|
),
|
||||||
// Padding(
|
// Padding(
|
||||||
|
@@ -70,36 +70,36 @@ class _FundTransferBeneficiaryScreenState
|
|||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('kangra central')) {
|
if (bankName != null && bankName.toLowerCase().contains('kangra central')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/icon.png',
|
'assets/images/icon.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('hdfc bank ltd')) {
|
if (bankName != null && bankName.toLowerCase().contains('hdfc bank ltd')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/hdfc_logo.png',
|
'assets/images/hdfc_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('icici bank ltd')) {
|
if (bankName != null && bankName.toLowerCase().contains('icici bank ltd')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/icici_logo.png',
|
'assets/images/icici_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (bankName != null && bankName.toLowerCase().contains('punjab national bank')) {
|
if (bankName != null &&
|
||||||
|
bankName.toLowerCase().contains('punjab national bank')) {
|
||||||
return Image.asset(
|
return Image.asset(
|
||||||
'assets/images/pnb_logo.png',
|
'assets/images/pnb_logo.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return const Icon(
|
return const Icon(
|
||||||
Icons.account_balance,
|
Icons.account_balance,
|
||||||
size: 40,
|
size: 40,
|
||||||
@@ -128,7 +128,8 @@ class _FundTransferBeneficiaryScreenState
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(beneficiary.accountNo),
|
Text(beneficiary.accountNo),
|
||||||
if (beneficiary.bankName != null && beneficiary.bankName!.isNotEmpty)
|
if (beneficiary.bankName != null &&
|
||||||
|
beneficiary.bankName!.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
beneficiary.bankName!,
|
beneficiary.bankName!,
|
||||||
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
|
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
|
||||||
|
@@ -87,7 +87,8 @@ class _FundTransferScreen extends State<FundTransferScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).fundTransfer,
|
AppLocalizations.of(context).fundTransfer,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: const [
|
actions: const [
|
||||||
|
@@ -27,7 +27,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_confettiController = ConfettiController(duration: const Duration(seconds: 2));
|
_confettiController =
|
||||||
|
ConfettiController(duration: const Duration(seconds: 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,7 +42,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
RenderRepaintBoundary boundary =
|
RenderRepaintBoundary boundary =
|
||||||
_shareKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
|
_shareKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
|
||||||
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
|
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
|
||||||
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
ByteData? byteData =
|
||||||
|
await image.toByteData(format: ui.ImageByteFormat.png);
|
||||||
Uint8List pngBytes = byteData!.buffer.asUint8List();
|
Uint8List pngBytes = byteData!.buffer.asUint8List();
|
||||||
|
|
||||||
final tempDir = await getTemporaryDirectory();
|
final tempDir = await getTemporaryDirectory();
|
||||||
@@ -129,7 +131,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
? Column(
|
? Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context).paymentSuccessful,
|
AppLocalizations.of(context)
|
||||||
|
.paymentSuccessful,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 22,
|
fontSize: 22,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -160,7 +163,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
"Date: ${response.date!.toLocal().toIso8601String()}",
|
"Date: ${response.date!.toLocal().toIso8601String()}",
|
||||||
style: const TextStyle(fontSize: 16),
|
style: const TextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
if (response.utr != null && response.utr!.isNotEmpty)
|
if (response.utr != null &&
|
||||||
|
response.utr!.isNotEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -182,7 +186,8 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
if (response.errorMessage != null)
|
if (response.errorMessage != null)
|
||||||
Text(response.errorMessage ?? '',
|
Text(
|
||||||
|
response.errorMessage ?? '',
|
||||||
style: const TextStyle(fontSize: 16),
|
style: const TextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -211,10 +216,13 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
style: TextStyle(color: Theme.of(context).primaryColor),
|
style: TextStyle(color: Theme.of(context).primaryColor),
|
||||||
),
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor:
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 32, vertical: 12),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
side: BorderSide(color: Theme.of(context).primaryColor, width: 1),
|
side: BorderSide(
|
||||||
|
color: Theme.of(context).primaryColor, width: 1),
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30),
|
||||||
),
|
),
|
||||||
textStyle: const TextStyle(
|
textStyle: const TextStyle(
|
||||||
@@ -226,12 +234,14 @@ class _PaymentAnimationScreenState extends State<PaymentAnimationScreen> {
|
|||||||
),
|
),
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
Navigator.of(context)
|
||||||
|
.popUntil((route) => route.isFirst);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.check),
|
icon: const Icon(Icons.check),
|
||||||
label: Text(AppLocalizations.of(context).done),
|
label: Text(AppLocalizations.of(context).done),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 45, vertical: 12),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 45, vertical: 12),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30),
|
||||||
),
|
),
|
||||||
|
@@ -131,7 +131,8 @@ class _TpinOtpScreenState extends State<TpinOtpScreen> {
|
|||||||
icon: const Icon(Icons.verified_user_rounded),
|
icon: const Icon(Icons.verified_user_rounded),
|
||||||
label: Text(
|
label: Text(
|
||||||
AppLocalizations.of(context).verifyOtp,
|
AppLocalizations.of(context).verifyOtp,
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
style: const TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: theme.colorScheme.primary,
|
backgroundColor: theme.colorScheme.primary,
|
||||||
|
@@ -41,7 +41,8 @@ class TpinSetupPromptScreen extends StatelessWidget {
|
|||||||
icon: const Icon(Icons.arrow_forward_rounded),
|
icon: const Icon(Icons.arrow_forward_rounded),
|
||||||
label: Text(
|
label: Text(
|
||||||
AppLocalizations.of(context).setTpin,
|
AppLocalizations.of(context).setTpin,
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
style:
|
||||||
|
const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: theme.colorScheme.primary,
|
backgroundColor: theme.colorScheme.primary,
|
||||||
|
@@ -173,7 +173,9 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
|
|||||||
key == '<' ? '⌫' : key,
|
key == '<' ? '⌫' : key,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: key == 'Enter' ? Theme.of(context).primaryColor : Colors.black,
|
color: key == 'Enter'
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -202,7 +204,8 @@ class _TpinSetScreenState extends State<TpinSetScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Icon(Icons.lock_outline, size: 60, color: Theme.of(context).primaryColor),
|
Icon(Icons.lock_outline,
|
||||||
|
size: 60, color: Theme.of(context).primaryColor),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
getTitle(),
|
getTitle(),
|
||||||
|
@@ -151,7 +151,8 @@ class _TransactionPinScreenState extends State<TransactionPinScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).tpin,
|
AppLocalizations.of(context).tpin,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
),
|
),
|
||||||
|
@@ -36,8 +36,8 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final String transactionDate = DateTime.now().toLocal().toString().split(
|
final String transactionDate = DateTime.now().toLocal().toString().split(
|
||||||
' ',
|
' ',
|
||||||
)[0];
|
)[0];
|
||||||
final String creditAccount = widget.creditAccount;
|
final String creditAccount = widget.creditAccount;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -53,12 +53,15 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
|
|||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
radius: 50,
|
radius: 50,
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
child: Icon(Icons.check, color: Theme.of(context).scaffoldBackgroundColor, size: 60),
|
child: Icon(Icons.check,
|
||||||
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
size: 60),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context).transactionSuccess,
|
AppLocalizations.of(context).transactionSuccess,
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
style: const TextStyle(
|
||||||
|
fontSize: 18, fontWeight: FontWeight.w600),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
@@ -92,7 +95,8 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
|
|||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
shape: const StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
foregroundColor: Theme.of(context).primaryColorLight,
|
foregroundColor: Theme.of(context).primaryColorLight,
|
||||||
side: const BorderSide(color: Colors.black, width: 1),
|
side: const BorderSide(color: Colors.black, width: 1),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
@@ -115,7 +119,8 @@ class _TransactionSuccessScreen extends State<TransactionSuccessScreen> {
|
|||||||
shape: const StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
backgroundColor: Theme.of(context).primaryColorDark,
|
backgroundColor: Theme.of(context).primaryColorDark,
|
||||||
foregroundColor: Theme.of(context).scaffoldBackgroundColor,
|
foregroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
),
|
),
|
||||||
child: Text(AppLocalizations.of(context).done),
|
child: Text(AppLocalizations.of(context).done),
|
||||||
),
|
),
|
||||||
|
@@ -37,4 +37,4 @@ class LanguageDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,8 @@ class PreferenceScreen extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => const LanguageDialog(), // your custom language dialog
|
builder: (_) =>
|
||||||
|
const LanguageDialog(), // your custom language dialog
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -38,28 +39,27 @@ class PreferenceScreen extends StatelessWidget {
|
|||||||
title: Text(AppLocalizations.of(context).themeMode),
|
title: Text(AppLocalizations.of(context).themeMode),
|
||||||
enabled: false,
|
enabled: false,
|
||||||
//trailing: Switch(
|
//trailing: Switch(
|
||||||
// value: state.isDarkMode,
|
// value: state.isDarkMode,
|
||||||
// onChanged: (val) {
|
// onChanged: (val) {
|
||||||
// context.read<ThemeCubit>().toggleDarkMode(val);
|
// context.read<ThemeCubit>().toggleDarkMode(val);
|
||||||
// },
|
// },
|
||||||
//),
|
//),
|
||||||
),
|
),
|
||||||
//Color_Theme_Selection
|
//Color_Theme_Selection
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.color_lens),
|
leading: const Icon(Icons.color_lens),
|
||||||
title: Text(AppLocalizations.of(context).themeColor),
|
title: Text(AppLocalizations.of(context).themeColor),
|
||||||
//enabled: false,
|
//enabled: false,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => const ColorThemeDialog(),
|
builder: (_) => const ColorThemeDialog(),
|
||||||
);
|
);
|
||||||
}
|
}),
|
||||||
),
|
],
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,8 @@ class ProfileScreen extends StatelessWidget {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const PreferenceScreen()),
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const PreferenceScreen()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@@ -142,7 +142,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
if (!_isBeneficiaryValidated) {
|
if (!_isBeneficiaryValidated) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(AppLocalizations.of(context).plsValidateBeneficiary)),
|
content:
|
||||||
|
Text(AppLocalizations.of(context).plsValidateBeneficiary)),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -189,8 +190,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
|
|
||||||
Navigator.of(pinScreenContext).pushReplacement(
|
Navigator.of(pinScreenContext).pushReplacement(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) =>
|
builder: (_) => PaymentAnimationScreen(
|
||||||
PaymentAnimationScreen(paymentResponse: completer.future),
|
paymentResponse: completer.future),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -229,8 +230,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
|
|
||||||
Navigator.of(pinScreenContext).pushReplacement(
|
Navigator.of(pinScreenContext).pushReplacement(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) =>
|
builder: (_) => PaymentAnimationScreen(
|
||||||
PaymentAnimationScreen(paymentResponse: completer.future),
|
paymentResponse: completer.future),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -273,7 +274,8 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).quickPayOutsideBank,
|
AppLocalizations.of(context).quickPayOutsideBank,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
@@ -385,9 +387,9 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
maxLength: 11,
|
maxLength: 11,
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
LengthLimitingTextInputFormatter(11),
|
LengthLimitingTextInputFormatter(11),
|
||||||
],
|
],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: AppLocalizations.of(context).ifscCode,
|
labelText: AppLocalizations.of(context).ifscCode,
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
@@ -446,16 +448,14 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
borderSide: BorderSide(color: Colors.black, width: 2),
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
items:
|
items: [
|
||||||
[
|
AppLocalizations.of(context).savings,
|
||||||
AppLocalizations.of(context).savings,
|
AppLocalizations.of(context).current,
|
||||||
AppLocalizations.of(context).current,
|
]
|
||||||
]
|
.map(
|
||||||
.map(
|
(e) => DropdownMenuItem(value: e, child: Text(e)),
|
||||||
(e) =>
|
)
|
||||||
DropdownMenuItem(value: e, child: Text(e)),
|
.toList(),
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
onChanged: (value) => setState(() {
|
onChanged: (value) => setState(() {
|
||||||
accountType = value!;
|
accountType = value!;
|
||||||
}),
|
}),
|
||||||
@@ -463,7 +463,6 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: bankNameController,
|
controller: bankNameController,
|
||||||
@@ -516,14 +515,14 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
onPressed: _isValidating
|
onPressed: _isValidating
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
if (confirmAccountNumberController
|
if (confirmAccountNumberController.text ==
|
||||||
.text ==
|
|
||||||
accountNumberController.text) {
|
accountNumberController.text) {
|
||||||
_validateBeneficiary();
|
_validateBeneficiary();
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
_validationError =
|
_validationError =
|
||||||
AppLocalizations.of(context).accountMismatch;
|
AppLocalizations.of(context)
|
||||||
|
.accountMismatch;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -531,10 +530,10 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
strokeWidth: 2),
|
|
||||||
)
|
)
|
||||||
: Text(AppLocalizations.of(context).validateBeneficiary),
|
: Text(
|
||||||
|
AppLocalizations.of(context).validateBeneficiary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -559,8 +558,7 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
borderSide: BorderSide(color: Colors.black),
|
borderSide: BorderSide(color: Colors.black),
|
||||||
),
|
),
|
||||||
focusedBorder: const OutlineInputBorder(
|
focusedBorder: const OutlineInputBorder(
|
||||||
borderSide:
|
borderSide: BorderSide(color: Colors.black, width: 2),
|
||||||
BorderSide(color: Colors.black, width: 2),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
@@ -645,15 +643,18 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SwipeButton.expand(
|
child: SwipeButton.expand(
|
||||||
thumb: Icon(Icons.arrow_forward, color: Theme.of(context).dialogBackgroundColor),
|
thumb: Icon(Icons.arrow_forward,
|
||||||
|
color: Theme.of(context).dialogBackgroundColor),
|
||||||
activeThumbColor: Theme.of(context).primaryColor,
|
activeThumbColor: Theme.of(context).primaryColor,
|
||||||
activeTrackColor: Theme.of(context).colorScheme.secondary.withAlpha(100),
|
activeTrackColor:
|
||||||
|
Theme.of(context).colorScheme.secondary.withAlpha(100),
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30),
|
||||||
height: 56,
|
height: 56,
|
||||||
onSwipe: _onProceedToPay,
|
onSwipe: _onProceedToPay,
|
||||||
child: Text(
|
child: Text(
|
||||||
AppLocalizations.of(context).swipeToPay,
|
AppLocalizations.of(context).swipeToPay,
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -679,10 +680,14 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isSelected ? Theme.of(context).primaryColor : Theme.of(context).scaffoldBackgroundColor,
|
color: isSelected
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Theme.of(context).scaffoldBackgroundColor,
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: isSelected ? Theme.of(context).primaryColor : Theme.of(context).scaffoldBackgroundColor,
|
color: isSelected
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Theme.of(context).scaffoldBackgroundColor,
|
||||||
width: isSelected ? 0 : 1.2,
|
width: isSelected ? 0 : 1.2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -698,4 +703,4 @@ class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -212,7 +212,8 @@ class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
|||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
_validationError =
|
_validationError =
|
||||||
AppLocalizations.of(context).accountMismatch;
|
AppLocalizations.of(context)
|
||||||
|
.accountMismatch;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -222,7 +223,8 @@ class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
|||||||
height: 20,
|
height: 20,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
)
|
)
|
||||||
: Text(AppLocalizations.of(context).validateBeneficiary),
|
: Text(
|
||||||
|
AppLocalizations.of(context).validateBeneficiary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -322,7 +324,8 @@ class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SwipeButton.expand(
|
child: SwipeButton.expand(
|
||||||
thumb: Icon(Icons.arrow_forward, color: Theme.of(context).dialogBackgroundColor),
|
thumb: Icon(Icons.arrow_forward,
|
||||||
|
color: Theme.of(context).dialogBackgroundColor),
|
||||||
activeThumbColor: Theme.of(context).primaryColor,
|
activeThumbColor: Theme.of(context).primaryColor,
|
||||||
activeTrackColor: Theme.of(
|
activeTrackColor: Theme.of(
|
||||||
context,
|
context,
|
||||||
@@ -337,8 +340,8 @@ class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
|||||||
if (_formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
if (!_isBeneficiaryValidated) {
|
if (!_isBeneficiaryValidated) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_validationError =
|
_validationError = AppLocalizations.of(context)
|
||||||
AppLocalizations.of(context).validateBeneficiaryproceeding;
|
.validateBeneficiaryproceeding;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,8 @@ class _ServiceScreen extends State<ServiceScreen> {
|
|||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context).services,
|
AppLocalizations.of(context).services,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
style:
|
||||||
|
const TextStyle(color: Colors.black, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
actions: [
|
actions: [
|
||||||
|
@@ -4,7 +4,7 @@ class Transaction {
|
|||||||
final double amount;
|
final double amount;
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
final String category;
|
final String category;
|
||||||
|
|
||||||
Transaction({
|
Transaction({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.description,
|
required this.description,
|
||||||
@@ -12,4 +12,4 @@ class Transaction {
|
|||||||
required this.date,
|
required this.date,
|
||||||
required this.category,
|
required this.category,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -62,7 +62,8 @@ import 'app_localizations_hi.dart';
|
|||||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||||
/// property.
|
/// property.
|
||||||
abstract class AppLocalizations {
|
abstract class AppLocalizations {
|
||||||
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
AppLocalizations(String locale)
|
||||||
|
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||||
|
|
||||||
final String localeName;
|
final String localeName;
|
||||||
|
|
||||||
@@ -70,7 +71,8 @@ abstract class AppLocalizations {
|
|||||||
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LocalizationsDelegate<AppLocalizations> delegate = _AppLocalizationsDelegate();
|
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||||
|
_AppLocalizationsDelegate();
|
||||||
|
|
||||||
/// A list of this localizations delegate along with the default localizations
|
/// A list of this localizations delegate along with the default localizations
|
||||||
/// delegates.
|
/// delegates.
|
||||||
@@ -82,7 +84,8 @@ abstract class AppLocalizations {
|
|||||||
/// Additional delegates can be added by appending to this list in
|
/// Additional delegates can be added by appending to this list in
|
||||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||||
/// of delegates is preferred or required.
|
/// of delegates is preferred or required.
|
||||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
|
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||||
|
<LocalizationsDelegate<dynamic>>[
|
||||||
delegate,
|
delegate,
|
||||||
GlobalMaterialLocalizations.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
@@ -1506,7 +1509,8 @@ abstract class AppLocalizations {
|
|||||||
String get validateBeneficiaryproceeding;
|
String get validateBeneficiaryproceeding;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
class _AppLocalizationsDelegate
|
||||||
|
extends LocalizationsDelegate<AppLocalizations> {
|
||||||
const _AppLocalizationsDelegate();
|
const _AppLocalizationsDelegate();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1515,25 +1519,25 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSupported(Locale locale) => <String>['en', 'hi'].contains(locale.languageCode);
|
bool isSupported(Locale locale) =>
|
||||||
|
<String>['en', 'hi'].contains(locale.languageCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||||
|
|
||||||
|
|
||||||
// Lookup logic when only language code is specified.
|
// Lookup logic when only language code is specified.
|
||||||
switch (locale.languageCode) {
|
switch (locale.languageCode) {
|
||||||
case 'en': return AppLocalizationsEn();
|
case 'en':
|
||||||
case 'hi': return AppLocalizationsHi();
|
return AppLocalizationsEn();
|
||||||
|
case 'hi':
|
||||||
|
return AppLocalizationsHi();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw FlutterError(
|
throw FlutterError(
|
||||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||||
'an issue with the localizations generation tool. Please file an issue '
|
'an issue with the localizations generation tool. Please file an issue '
|
||||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||||
'that was used.'
|
'that was used.');
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@@ -486,7 +486,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get otpVerification => 'OTP Verification';
|
String get otpVerification => 'OTP Verification';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get otpSentMessage => 'Enter the 4-digit OTP sent to your mobile number';
|
String get otpSentMessage =>
|
||||||
|
'Enter the 4-digit OTP sent to your mobile number';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get verifyOtp => 'Verify OTP';
|
String get verifyOtp => 'Verify OTP';
|
||||||
@@ -504,13 +505,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get tpinRequired => 'TPIN Required';
|
String get tpinRequired => 'TPIN Required';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinRequiredMessage => 'You need to set your TPIN to continue with secure transactions';
|
String get tpinRequiredMessage =>
|
||||||
|
'You need to set your TPIN to continue with secure transactions';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get setTpinTitle => 'Set TPIN';
|
String get setTpinTitle => 'Set TPIN';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinInfo => 'Your TPIN is a 6-digit code used to authorize transactions. Keep it safe and do not share it with anyone.';
|
String get tpinInfo =>
|
||||||
|
'Your TPIN is a 6-digit code used to authorize transactions. Keep it safe and do not share it with anyone.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinFailed => 'Failed to set TPIN. Please try again.';
|
String get tpinFailed => 'Failed to set TPIN. Please try again.';
|
||||||
@@ -564,7 +567,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get enableFingerprintLogin => 'Enable Fingerprint Login?';
|
String get enableFingerprintLogin => 'Enable Fingerprint Login?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enableFingerprintMessage => 'Would you like to enable fingerprint authentication for faster login?';
|
String get enableFingerprintMessage =>
|
||||||
|
'Would you like to enable fingerprint authentication for faster login?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no => 'No';
|
String get no => 'No';
|
||||||
@@ -585,7 +589,8 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get loading => 'Loading......';
|
String get loading => 'Loading......';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enableFingerprintQuick => 'Enable fingerprint authentication for quick login?';
|
String get enableFingerprintQuick =>
|
||||||
|
'Enable fingerprint authentication for quick login?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kccb => 'KCCB';
|
String get kccb => 'KCCB';
|
||||||
@@ -687,13 +692,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get invalidRtgs => 'Invalid Amount for RTGS';
|
String get invalidRtgs => 'Invalid Amount for RTGS';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidRtgsPopUp => 'RTGS transactions require a minimum amount of 200,000. Please enter a higher amount or select NEFT as the transaction mode.';
|
String get invalidRtgsPopUp =>
|
||||||
|
'RTGS transactions require a minimum amount of 200,000. Please enter a higher amount or select NEFT as the transaction mode.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get correctTpin => 'Please Enter the correct TPIN';
|
String get correctTpin => 'Please Enter the correct TPIN';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get insufficientFund => 'Your account does not have sufficient balance';
|
String get insufficientFund =>
|
||||||
|
'Your account does not have sufficient balance';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get creditedTo => 'Credited To';
|
String get creditedTo => 'Credited To';
|
||||||
@@ -705,11 +712,13 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get proceed => 'Proceed';
|
String get proceed => 'Proceed';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get plsValidateBeneficiary => 'Please validate beneficiary details first';
|
String get plsValidateBeneficiary =>
|
||||||
|
'Please validate beneficiary details first';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get accno7to20 => 'Account number must be between 7 and 20 digits';
|
String get accno7to20 => 'Account number must be between 7 and 20 digits';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get validateBeneficiaryproceeding => 'Please validate beneficiary before proceeding';
|
String get validateBeneficiaryproceeding =>
|
||||||
|
'Please validate beneficiary before proceeding';
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get enableBiometric => 'बायोमेट्रिक प्रमाणीकरण सक्षम करें';
|
String get enableBiometric => 'बायोमेट्रिक प्रमाणीकरण सक्षम करें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useBiometricPrompt => 'तेज़ लॉगिन के लिए फिंगरप्रिंट/फेस आईडी का उपयोग करें?';
|
String get useBiometricPrompt =>
|
||||||
|
'तेज़ लॉगिन के लिए फिंगरप्रिंट/फेस आईडी का उपयोग करें?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get later => 'बाद में';
|
String get later => 'बाद में';
|
||||||
@@ -486,7 +487,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get otpVerification => 'ओटीपी सत्यापन';
|
String get otpVerification => 'ओटीपी सत्यापन';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get otpSentMessage => 'अपने मोबाइल नंबर पर भेजा गया 4-अंकों का ओटीपी दर्ज करें';
|
String get otpSentMessage =>
|
||||||
|
'अपने मोबाइल नंबर पर भेजा गया 4-अंकों का ओटीपी दर्ज करें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get verifyOtp => 'ओटीपी सत्यापित करें';
|
String get verifyOtp => 'ओटीपी सत्यापित करें';
|
||||||
@@ -504,13 +506,15 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get tpinRequired => 'टी-पिन आवश्यक है';
|
String get tpinRequired => 'टी-पिन आवश्यक है';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinRequiredMessage => 'सुरक्षित लेनदेन के लिए टी-पिन सेट करना आवश्यक है';
|
String get tpinRequiredMessage =>
|
||||||
|
'सुरक्षित लेनदेन के लिए टी-पिन सेट करना आवश्यक है';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get setTpinTitle => 'टी-पिन सेट करें';
|
String get setTpinTitle => 'टी-पिन सेट करें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinInfo => 'आपका टी-पिन 6 अंकों का कोड है जिसका उपयोग लेन-देन को प्रमाणित करने के लिए किया जाता है। इसे सुरक्षित रखें और किसी से साझा न करें।';
|
String get tpinInfo =>
|
||||||
|
'आपका टी-पिन 6 अंकों का कोड है जिसका उपयोग लेन-देन को प्रमाणित करने के लिए किया जाता है। इसे सुरक्षित रखें और किसी से साझा न करें।';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tpinFailed => 'टी-पिन सेट करने में विफल। कृपया पुनः प्रयास करें।';
|
String get tpinFailed => 'टी-पिन सेट करने में विफल। कृपया पुनः प्रयास करें।';
|
||||||
@@ -564,7 +568,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get enableFingerprintLogin => 'फिंगरप्रिंट लॉगिन सक्षम करें?';
|
String get enableFingerprintLogin => 'फिंगरप्रिंट लॉगिन सक्षम करें?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enableFingerprintMessage => 'क्या आप तेज लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करना चाहेंगे?';
|
String get enableFingerprintMessage =>
|
||||||
|
'क्या आप तेज लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करना चाहेंगे?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no => 'नहीं';
|
String get no => 'नहीं';
|
||||||
@@ -573,7 +578,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get yes => 'हाँ';
|
String get yes => 'हाँ';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get authenticateToEnable => 'फिंगरप्रिंट लॉगिन सक्षम करने के लिए प्रमाणीकरण करें';
|
String get authenticateToEnable =>
|
||||||
|
'फिंगरप्रिंट लॉगिन सक्षम करने के लिए प्रमाणीकरण करें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get exitApp => 'ऐप बंद करें';
|
String get exitApp => 'ऐप बंद करें';
|
||||||
@@ -585,7 +591,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get loading => 'लोड हो रहा है......';
|
String get loading => 'लोड हो रहा है......';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enableFingerprintQuick => 'तेज़ लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करें?';
|
String get enableFingerprintQuick =>
|
||||||
|
'तेज़ लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करें?';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get kccb => 'केसीसीबी';
|
String get kccb => 'केसीसीबी';
|
||||||
@@ -687,7 +694,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get invalidRtgs => 'RTGS के लिए अमान्य राशि';
|
String get invalidRtgs => 'RTGS के लिए अमान्य राशि';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get invalidRtgsPopUp => 'RTGS लेनदेन के लिए न्यूनतम 2,00,000 रुपये की राशि की आवश्यकता होती है। कृपया अधिक राशि दर्ज करें या लेनदेन मोड के रूप में NEFT चुनें';
|
String get invalidRtgsPopUp =>
|
||||||
|
'RTGS लेनदेन के लिए न्यूनतम 2,00,000 रुपये की राशि की आवश्यकता होती है। कृपया अधिक राशि दर्ज करें या लेनदेन मोड के रूप में NEFT चुनें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get correctTpin => 'कृपया सही टी-पिन दर्ज करें';
|
String get correctTpin => 'कृपया सही टी-पिन दर्ज करें';
|
||||||
@@ -705,11 +713,13 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||||||
String get proceed => 'आगे बढ़ना';
|
String get proceed => 'आगे बढ़ना';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get plsValidateBeneficiary => 'कृपया पहले लाभार्थी विवरण सत्यापित करें';
|
String get plsValidateBeneficiary =>
|
||||||
|
'कृपया पहले लाभार्थी विवरण सत्यापित करें';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get accno7to20 => 'खाता संख्या सात से बीस अंकों के बीच होनी चाहिए';
|
String get accno7to20 => 'खाता संख्या सात से बीस अंकों के बीच होनी चाहिए';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get validateBeneficiaryproceeding => 'कृपया आगे बढ़ने से पहले लाभार्थी को पट्टे पर मान्य करें';
|
String get validateBeneficiaryproceeding =>
|
||||||
|
'कृपया आगे बढ़ने से पहले लाभार्थी को पट्टे पर मान्य करें';
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,6 @@ void main() async {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Initialize dependencies
|
// Initialize dependencies
|
||||||
await setupDependencies();
|
await setupDependencies();
|
||||||
runApp(const KMobile());
|
runApp(const KMobile());
|
||||||
}
|
}
|
||||||
|
@@ -3,33 +3,30 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|||||||
|
|
||||||
class SecureStorage {
|
class SecureStorage {
|
||||||
final FlutterSecureStorage _storage;
|
final FlutterSecureStorage _storage;
|
||||||
|
|
||||||
SecureStorage(): _storage = const FlutterSecureStorage();
|
SecureStorage() : _storage = const FlutterSecureStorage();
|
||||||
|
|
||||||
Future<void> write(String key, dynamic value) async {
|
Future<void> write(String key, dynamic value) async {
|
||||||
final stringValue = value is String
|
final stringValue = value is String ? value : json.encode(value);
|
||||||
? value
|
|
||||||
: json.encode(value);
|
|
||||||
await _storage.write(key: key, value: stringValue);
|
await _storage.write(key: key, value: stringValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> read(String key) async {
|
Future<dynamic> read(String key) async {
|
||||||
final value = await _storage.read(key: key);
|
final value = await _storage.read(key: key);
|
||||||
if (value == null) return null;
|
if (value == null) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return json.decode(value);
|
return json.decode(value);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> delete(String key) async {
|
Future<void> delete(String key) async {
|
||||||
await _storage.delete(key: key);
|
await _storage.delete(key: key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteAll() async {
|
Future<void> deleteAll() async {
|
||||||
await _storage.deleteAll();
|
await _storage.deleteAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
Reference in New Issue
Block a user