dart format
This commit is contained in:
@@ -142,7 +142,7 @@ class AuthService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future setTncflag() async{
|
Future setTncflag() async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.post(
|
final response = await _dio.post(
|
||||||
'/api/auth/tnc',
|
'/api/auth/tnc',
|
||||||
@@ -151,15 +151,13 @@ class AuthService {
|
|||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
throw AuthException('Failed to proceed with T&C');
|
throw AuthException('Failed to proceed with T&C');
|
||||||
}
|
}
|
||||||
}
|
} on DioException catch (e) {
|
||||||
on DioException catch (e) {
|
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
throw NetworkException('Network error during T&C Setup');
|
throw NetworkException('Network error during T&C Setup');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw UnexpectedException(
|
throw UnexpectedException('Unexpected error: ${e.toString()}');
|
||||||
'Unexpected error: ${e.toString()}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ class LimitService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void editLimit( double newLimit) async {
|
void editLimit(double newLimit) async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.post('/api/customer/daily-limit',
|
final response = await _dio.post('/api/customer/daily-limit',
|
||||||
data: '{"amount": $newLimit}');
|
data: '{"amount": $newLimit}');
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import '../features/dashboard/screens/dashboard_screen.dart';
|
|||||||
// import '../features/transactions/screens/transactions_screen.dart';
|
// import '../features/transactions/screens/transactions_screen.dart';
|
||||||
// import '../features/payments/screens/payments_screen.dart';
|
// import '../features/payments/screens/payments_screen.dart';
|
||||||
// import '../features/settings/screens/settings_screen.dart';
|
// import '../features/settings/screens/settings_screen.dart';
|
||||||
import 'package:kmobile/features/auth/screens/tnc_required_screen.dart';
|
import 'package:kmobile/features/auth/screens/tnc_required_screen.dart';
|
||||||
|
|
||||||
class AppRoutes {
|
class AppRoutes {
|
||||||
// Private constructor to prevent instantiation
|
// Private constructor to prevent instantiation
|
||||||
@@ -36,7 +36,8 @@ class AppRoutes {
|
|||||||
case login:
|
case login:
|
||||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||||
case TncRequiredScreen.routeName: // Renamed class
|
case TncRequiredScreen.routeName: // Renamed class
|
||||||
return MaterialPageRoute(builder: (_) => const TncRequiredScreen()); // Renamed class
|
return MaterialPageRoute(
|
||||||
|
builder: (_) => const TncRequiredScreen()); // Renamed class
|
||||||
case mPin:
|
case mPin:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => const MPinScreen(
|
builder: (_) => const MPinScreen(
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ class Beneficiary {
|
|||||||
return Beneficiary(
|
return Beneficiary(
|
||||||
accountNo: json['account_no'] ?? json['accountNo'] ?? '',
|
accountNo: json['account_no'] ?? json['accountNo'] ?? '',
|
||||||
accountType: json['account_type'] ?? json['accountType'] ?? '',
|
accountType: json['account_type'] ?? json['accountType'] ?? '',
|
||||||
createdAt: json['createdAt'] == null ? null : DateTime.tryParse(json['createdAt']),
|
createdAt: json['createdAt'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.tryParse(json['createdAt']),
|
||||||
name: json['name'] ?? '',
|
name: json['name'] ?? '',
|
||||||
ifscCode: json['ifsc_code'] ?? json['ifscCode'] ?? '',
|
ifscCode: json['ifsc_code'] ?? json['ifscCode'] ?? '',
|
||||||
bankName: json['bank_name'] ?? json['bankName'] ?? '',
|
bankName: json['bank_name'] ?? json['bankName'] ?? '',
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ class AuthRepository {
|
|||||||
|
|
||||||
AuthRepository(this._authService, this._userService, this._secureStorage);
|
AuthRepository(this._authService, this._userService, this._secureStorage);
|
||||||
|
|
||||||
Future<(List<User>, AuthToken)> login(String customerNo, String password) async {
|
Future<(List<User>, AuthToken)> login(
|
||||||
|
String customerNo, String password) async {
|
||||||
// Create credentials and call service
|
// Create credentials and call service
|
||||||
final credentials =
|
final credentials =
|
||||||
AuthCredentials(customerNo: customerNo, password: password);
|
AuthCredentials(customerNo: customerNo, password: password);
|
||||||
@@ -64,7 +65,8 @@ class AuthRepository {
|
|||||||
final authToken = AuthToken(
|
final authToken = AuthToken(
|
||||||
accessToken: accessToken,
|
accessToken: accessToken,
|
||||||
expiresAt: DateTime.parse(expiryString),
|
expiresAt: DateTime.parse(expiryString),
|
||||||
tnc: tncString == 'true', // Parse 'true' string to true, otherwise false
|
tnc:
|
||||||
|
tncString == 'true', // Parse 'true' string to true, otherwise false
|
||||||
);
|
);
|
||||||
return authToken;
|
return authToken;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ Future<void> setupDependencies() async {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Register controllers/cubits
|
// Register controllers/cubits
|
||||||
getIt.registerFactory<AuthCubit>(
|
getIt.registerFactory<AuthCubit>(() => AuthCubit(
|
||||||
() => AuthCubit(getIt<AuthRepository>(), getIt<UserService>(), getIt<SecureStorage>()));
|
getIt<AuthRepository>(), getIt<UserService>(), getIt<SecureStorage>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Dio _createDioClient() {
|
Dio _createDioClient() {
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
Future<void> login(String customerNo, String password) async {
|
Future<void> login(String customerNo, String password) async {
|
||||||
emit(AuthLoading());
|
emit(AuthLoading());
|
||||||
try {
|
try {
|
||||||
final (users, authToken) = await _authRepository.login(customerNo, password);
|
final (users, authToken) =
|
||||||
|
await _authRepository.login(customerNo, password);
|
||||||
|
|
||||||
if (authToken.tnc == false) {
|
if (authToken.tnc == false) {
|
||||||
emit(ShowTncDialog(authToken, users));
|
emit(ShowTncDialog(authToken, users));
|
||||||
@@ -57,7 +58,6 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> onTncDialogResult(
|
Future<void> onTncDialogResult(
|
||||||
bool agreed, AuthToken authToken, List<User> users) async {
|
bool agreed, AuthToken authToken, List<User> users) async {
|
||||||
if (agreed) {
|
if (agreed) {
|
||||||
@@ -83,7 +83,6 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> _checkMpinAndNavigate(List<User> users) async {
|
Future<void> _checkMpinAndNavigate(List<User> users) async {
|
||||||
final mpin = await _secureStorage.read('mpin');
|
final mpin = await _secureStorage.read('mpin');
|
||||||
if (mpin == null) {
|
if (mpin == null) {
|
||||||
@@ -94,5 +93,4 @@ class AuthCubit extends Cubit<AuthState> {
|
|||||||
emit(Authenticated(users));
|
emit(Authenticated(users));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ class ShowTncDialog extends AuthState {
|
|||||||
// States to trigger specific navigations from the UI
|
// States to trigger specific navigations from the UI
|
||||||
class NavigateToTncRequiredScreen extends AuthState {}
|
class NavigateToTncRequiredScreen extends AuthState {}
|
||||||
|
|
||||||
class NavigateToMpinSetupScreen extends AuthState {
|
class NavigateToMpinSetupScreen extends AuthState {
|
||||||
final List<User> users;
|
final List<User> users;
|
||||||
|
|
||||||
const NavigateToMpinSetupScreen(this.users);
|
const NavigateToMpinSetupScreen(this.users);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [users];
|
List<Object> get props => [users];
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavigateToDashboardScreen extends AuthState {}
|
class NavigateToDashboardScreen extends AuthState {}
|
||||||
@@ -28,10 +28,11 @@ class AuthToken extends Equatable {
|
|||||||
|
|
||||||
return AuthToken(
|
return AuthToken(
|
||||||
accessToken: token,
|
accessToken: token,
|
||||||
expiresAt: _decodeExpiryFromToken(token), // This method is still valid for JWT expiry
|
expiresAt: _decodeExpiryFromToken(
|
||||||
|
token), // This method is still valid for JWT expiry
|
||||||
tnc: tncMobileValue, // Use the correctly extracted value
|
tnc: tncMobileValue, // Use the correctly extracted value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DateTime _decodeExpiryFromToken(String token) {
|
static DateTime _decodeExpiryFromToken(String token) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -255,7 +255,8 @@ class LoginScreenState extends State<LoginScreen>
|
|||||||
} else if (state is NavigateToTncRequiredScreen) {
|
} else if (state is NavigateToTncRequiredScreen) {
|
||||||
Navigator.of(context).pushNamed(TncRequiredScreen.routeName);
|
Navigator.of(context).pushNamed(TncRequiredScreen.routeName);
|
||||||
} else if (state is NavigateToMpinSetupScreen) {
|
} else if (state is NavigateToMpinSetupScreen) {
|
||||||
Navigator.of(context).push( // Use push, NOT pushReplacement
|
Navigator.of(context).push(
|
||||||
|
// Use push, NOT pushReplacement
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) => MPinScreen(
|
builder: (_) => MPinScreen(
|
||||||
mode: MPinMode.set,
|
mode: MPinMode.set,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TncRequiredScreen extends StatelessWidget { // Renamed class
|
class TncRequiredScreen extends StatelessWidget {
|
||||||
|
// Renamed class
|
||||||
const TncRequiredScreen({Key? key}) : super(key: key);
|
const TncRequiredScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
static const routeName = '/tnc-required';
|
static const routeName = '/tnc-required';
|
||||||
@@ -36,4 +37,4 @@
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,7 +269,9 @@ class _DashboardScreenState extends State<DashboardScreen>
|
|||||||
final users = state.users;
|
final users = state.users;
|
||||||
final currAccount = users[selectedAccountIndex];
|
final currAccount = users[selectedAccountIndex];
|
||||||
final accountType = currAccount.accountType?.toLowerCase();
|
final accountType = currAccount.accountType?.toLowerCase();
|
||||||
final isPaymentDisabled = accountType != 'sa' && accountType != 'sb' && accountType != 'ca';
|
final isPaymentDisabled = accountType != 'sa' &&
|
||||||
|
accountType != 'sb' &&
|
||||||
|
accountType != 'ca';
|
||||||
// first‐time load
|
// first‐time load
|
||||||
if (!_txInitialized) {
|
if (!_txInitialized) {
|
||||||
_txInitialized = true;
|
_txInitialized = true;
|
||||||
@@ -509,8 +511,7 @@ class _DashboardScreenState extends State<DashboardScreen>
|
|||||||
users[selectedAccountIndex]
|
users[selectedAccountIndex]
|
||||||
.accountNo!,
|
.accountNo!,
|
||||||
remitterName:
|
remitterName:
|
||||||
users[selectedAccountIndex]
|
users[selectedAccountIndex].name!,
|
||||||
.name!,
|
|
||||||
// Pass the full list of accounts
|
// Pass the full list of accounts
|
||||||
accounts: users)));
|
accounts: users)));
|
||||||
}, disable: isPaymentDisabled),
|
}, disable: isPaymentDisabled),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class CooldownTimer extends StatefulWidget {
|
class CooldownTimer extends StatefulWidget {
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final VoidCallback onTimerFinish;
|
final VoidCallback onTimerFinish;
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
_CooldownTimerState createState() => _CooldownTimerState();
|
_CooldownTimerState createState() => _CooldownTimerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CooldownTimerState extends State<CooldownTimer> {
|
class _CooldownTimerState extends State<CooldownTimer> {
|
||||||
late Timer _timer;
|
late Timer _timer;
|
||||||
late Duration _timeRemaining;
|
late Duration _timeRemaining;
|
||||||
|
|
||||||
@@ -62,7 +62,8 @@
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_timeRemaining == Duration.zero) {
|
if (_timeRemaining == Duration.zero) {
|
||||||
return const SizedBox.shrink(); // Or some other widget indicating it's enabled
|
return const SizedBox
|
||||||
|
.shrink(); // Or some other widget indicating it's enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@@ -87,4 +88,4 @@
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,21 +43,22 @@ class FundTransferAmountScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
|
||||||
final _limitService = getIt<LimitService>();
|
final _limitService = getIt<LimitService>();
|
||||||
Limit? _limit;
|
Limit? _limit;
|
||||||
bool _isLoadingLimit = true;
|
bool _isLoadingLimit = true;
|
||||||
bool _isAmountOverLimit = false;
|
bool _isAmountOverLimit = false;
|
||||||
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
||||||
final _amountController = TextEditingController();
|
final _amountController = TextEditingController();
|
||||||
final _remarksController = TextEditingController();
|
final _remarksController = TextEditingController();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
TransactionMode _selectedMode = TransactionMode.neft;
|
TransactionMode _selectedMode = TransactionMode.neft;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadLimit(); // Call the new method
|
_loadLimit(); // Call the new method
|
||||||
_amountController.addListener(_checkAmountLimit);
|
_amountController.addListener(_checkAmountLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadLimit() async {
|
Future<void> _loadLimit() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoadingLimit = true;
|
_isLoadingLimit = true;
|
||||||
@@ -77,7 +78,7 @@ void initState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add this method to check the amount against the limit
|
// Add this method to check the amount against the limit
|
||||||
void _checkAmountLimit() {
|
void _checkAmountLimit() {
|
||||||
if (_limit == null) return;
|
if (_limit == null) return;
|
||||||
|
|
||||||
final amount = double.tryParse(_amountController.text) ?? 0;
|
final amount = double.tryParse(_amountController.text) ?? 0;
|
||||||
@@ -87,7 +88,8 @@ void _checkAmountLimit() {
|
|||||||
if (isOverLimit) {
|
if (isOverLimit) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
content: Text(
|
||||||
|
'Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -98,7 +100,7 @@ void _checkAmountLimit() {
|
|||||||
_isAmountOverLimit = isOverLimit;
|
_isAmountOverLimit = isOverLimit;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@@ -487,8 +489,7 @@ void _checkAmountLimit() {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (_isLoadingLimit)
|
if (_isLoadingLimit) const Text('Fetching daily limit...'),
|
||||||
const Text('Fetching daily limit...'),
|
|
||||||
if (!_isLoadingLimit && _limit != null)
|
if (!_isLoadingLimit && _limit != null)
|
||||||
Text(
|
Text(
|
||||||
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
||||||
@@ -506,7 +507,7 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
child: Text(AppLocalizations.of(context).proceed),
|
child: Text(AppLocalizations.of(context).proceed),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ class _FundTransferBeneficiaryScreenState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Widget _buildBeneficiaryList() {
|
Widget _buildBeneficiaryList() {
|
||||||
if (_beneficiaries.isEmpty) {
|
if (_beneficiaries.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
@@ -155,7 +154,6 @@ class _FundTransferBeneficiaryScreenState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:kmobile/data/models/user.dart';
|
import 'package:kmobile/data/models/user.dart';
|
||||||
import 'package:kmobile/features/auth/controllers/auth_cubit.dart';
|
import 'package:kmobile/features/auth/controllers/auth_cubit.dart';
|
||||||
import 'package:kmobile/features/auth/controllers/auth_state.dart';
|
import 'package:kmobile/features/auth/controllers/auth_state.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart';
|
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart';
|
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import '../../../l10n/app_localizations.dart'; // Keep localizations
|
import '../../../l10n/app_localizations.dart'; // Keep localizations
|
||||||
|
|
||||||
class FundTransferScreen extends StatelessWidget {
|
class FundTransferScreen extends StatelessWidget {
|
||||||
final String creditAccountNo;
|
final String creditAccountNo;
|
||||||
final String remitterName;
|
final String remitterName;
|
||||||
final List<User> accounts; // Continue to accept the list of accounts
|
final List<User> accounts; // Continue to accept the list of accounts
|
||||||
@@ -97,9 +97,9 @@
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FundTransferManagementTile extends StatelessWidget {
|
class FundTransferManagementTile extends StatelessWidget {
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String label;
|
final String label;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
@@ -123,4 +123,4 @@
|
|||||||
enabled: !disable,
|
enabled: !disable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:kmobile/data/models/user.dart';
|
import 'package:kmobile/data/models/user.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart';
|
import 'package:kmobile/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart';
|
||||||
import 'package:kmobile/widgets/bank_logos.dart';
|
import 'package:kmobile/widgets/bank_logos.dart';
|
||||||
|
|
||||||
class FundTransferSelfAccountsScreen extends StatelessWidget {
|
class FundTransferSelfAccountsScreen extends StatelessWidget {
|
||||||
final String debitAccountNo;
|
final String debitAccountNo;
|
||||||
final String remitterName;
|
final String remitterName;
|
||||||
final List<User> accounts;
|
final List<User> accounts;
|
||||||
@@ -57,8 +57,8 @@
|
|||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
radius: 24,
|
radius: 24,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
child:
|
child: getBankLogo(
|
||||||
getBankLogo('Kangra Central Co-operative Bank', context),
|
'Kangra Central Co-operative Bank', context),
|
||||||
),
|
),
|
||||||
title: Text(account.name ?? 'N/A'),
|
title: Text(account.name ?? 'N/A'),
|
||||||
subtitle: Column(
|
subtitle: Column(
|
||||||
@@ -67,8 +67,7 @@
|
|||||||
Text(account.accountNo ?? 'N/A'),
|
Text(account.accountNo ?? 'N/A'),
|
||||||
Text(
|
Text(
|
||||||
_getFullAccountType(account.accountType),
|
_getFullAccountType(account.accountType),
|
||||||
style:
|
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
|
||||||
TextStyle(fontSize: 12, color: Colors.grey[600]),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -91,4 +90,4 @@
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:kmobile/api/services/limit_service.dart';
|
import 'package:kmobile/api/services/limit_service.dart';
|
||||||
import 'package:kmobile/api/services/payment_service.dart';
|
import 'package:kmobile/api/services/payment_service.dart';
|
||||||
import 'package:kmobile/data/models/transfer.dart';
|
import 'package:kmobile/data/models/transfer.dart';
|
||||||
import 'package:kmobile/data/models/user.dart';
|
import 'package:kmobile/data/models/user.dart';
|
||||||
import 'package:kmobile/di/injection.dart';
|
import 'package:kmobile/di/injection.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/payment_animation.dart';
|
import 'package:kmobile/features/fund_transfer/screens/payment_animation.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
|
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
|
||||||
import 'package:kmobile/widgets/bank_logos.dart';
|
import 'package:kmobile/widgets/bank_logos.dart';
|
||||||
|
|
||||||
class FundTransferSelfAmountScreen extends StatefulWidget {
|
class FundTransferSelfAmountScreen extends StatefulWidget {
|
||||||
final String debitAccountNo;
|
final String debitAccountNo;
|
||||||
final User creditAccount;
|
final User creditAccount;
|
||||||
final String remitterName;
|
final String remitterName;
|
||||||
@@ -24,9 +24,9 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
@override
|
@override
|
||||||
State<FundTransferSelfAmountScreen> createState() =>
|
State<FundTransferSelfAmountScreen> createState() =>
|
||||||
_FundTransferSelfAmountScreenState();
|
_FundTransferSelfAmountScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FundTransferSelfAmountScreenState
|
class _FundTransferSelfAmountScreenState
|
||||||
extends State<FundTransferSelfAmountScreen> {
|
extends State<FundTransferSelfAmountScreen> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _amountController = TextEditingController();
|
final _amountController = TextEditingController();
|
||||||
@@ -39,12 +39,12 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
bool _isAmountOverLimit = false;
|
bool _isAmountOverLimit = false;
|
||||||
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadLimit(); // Fetch the daily limit
|
_loadLimit(); // Fetch the daily limit
|
||||||
_amountController.addListener(_checkAmountLimit); // Listen for amount changes
|
_amountController
|
||||||
|
.addListener(_checkAmountLimit); // Listen for amount changes
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -119,8 +119,8 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
|
|
||||||
Navigator.of(pinScreenContext).pushReplacement(
|
Navigator.of(pinScreenContext).pushReplacement(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) =>
|
builder: (_) => PaymentAnimationScreen(
|
||||||
PaymentAnimationScreen(paymentResponse: paymentResponseFuture),
|
paymentResponse: paymentResponseFuture),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -173,8 +173,8 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading:
|
leading: getBankLogo(
|
||||||
getBankLogo('Kangra Central Co-operative Bank', context),
|
'Kangra Central Co-operative Bank', context),
|
||||||
title: Text(widget.creditAccount.name ?? 'N/A'),
|
title: Text(widget.creditAccount.name ?? 'N/A'),
|
||||||
subtitle: Text(widget.creditAccount.accountNo ?? 'N/A'),
|
subtitle: Text(widget.creditAccount.accountNo ?? 'N/A'),
|
||||||
),
|
),
|
||||||
@@ -214,8 +214,7 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// Daily Limit Display
|
// Daily Limit Display
|
||||||
if (_isLoadingLimit)
|
if (_isLoadingLimit) const Text('Fetching daily limit...'),
|
||||||
const Text('Fetching daily limit...'),
|
|
||||||
if (!_isLoadingLimit && _limit != null)
|
if (!_isLoadingLimit && _limit != null)
|
||||||
Text(
|
Text(
|
||||||
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
||||||
@@ -242,4 +241,4 @@ import 'package:kmobile/widgets/bank_logos.dart';
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class _DailyLimitScreenState extends State<DailyLimitScreen> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showAddOrEditLimitDialog() async {
|
Future<void> _showAddOrEditLimitDialog() async {
|
||||||
_limitController.text = _currentLimit?.toStringAsFixed(0) ?? '';
|
_limitController.text = _currentLimit?.toStringAsFixed(0) ?? '';
|
||||||
final newLimit = await showDialog<double>(
|
final newLimit = await showDialog<double>(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -81,7 +81,8 @@ Future<void> _showAddOrEditLimitDialog() async {
|
|||||||
if (value > 200000) {
|
if (value > 200000) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: const Text("Limit To be Set must be less than 200000"),
|
content: const Text(
|
||||||
|
"Limit To be Set must be less than 200000"),
|
||||||
behavior: SnackBarBehavior.floating,
|
behavior: SnackBarBehavior.floating,
|
||||||
backgroundColor: theme.colorScheme.error,
|
backgroundColor: theme.colorScheme.error,
|
||||||
),
|
),
|
||||||
@@ -108,8 +109,7 @@ Future<void> _showAddOrEditLimitDialog() async {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _removeLimit() {
|
void _removeLimit() {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -129,13 +129,14 @@ Future<void> _showAddOrEditLimitDialog() async {
|
|||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_currentLimit = limit?.dailyLimit;
|
_currentLimit = limit?.dailyLimit;
|
||||||
_spentAmount = limit?.usedLimit;
|
_spentAmount = limit?.usedLimit;
|
||||||
final localizations = AppLocalizations.of(context);
|
final localizations = AppLocalizations.of(context);
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
final formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
||||||
final remainingLimit = _currentLimit != null ? _currentLimit! - _spentAmount! : 0.0;
|
final remainingLimit =
|
||||||
|
_currentLimit != null ? _currentLimit! - _spentAmount! : 0.0;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import 'package:kmobile/features/profile/preferences/preference_screen.dart';
|
|||||||
import 'package:kmobile/api/services/auth_service.dart';
|
import 'package:kmobile/api/services/auth_service.dart';
|
||||||
import 'package:kmobile/features/fund_transfer/screens/tpin_set_screen.dart';
|
import 'package:kmobile/features/fund_transfer/screens/tpin_set_screen.dart';
|
||||||
|
|
||||||
|
|
||||||
class ProfileScreen extends StatefulWidget {
|
class ProfileScreen extends StatefulWidget {
|
||||||
final String mobileNumber;
|
final String mobileNumber;
|
||||||
const ProfileScreen({super.key, required this.mobileNumber});
|
const ProfileScreen({super.key, required this.mobileNumber});
|
||||||
@@ -210,7 +209,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text('TPIN Not Set'),
|
title: Text('TPIN Not Set'),
|
||||||
content: Text('You have not set a TPIN yet. Please set a TPIN to proceed.'),
|
content: Text(
|
||||||
|
'You have not set a TPIN yet. Please set a TPIN to proceed.'),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('Back'),
|
child: Text('Back'),
|
||||||
@@ -236,14 +236,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Case 2: TPIN is set
|
// Case 2: TPIN is set
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ChangeTpinScreen(mobileNumber: widget.mobileNumber),
|
builder: (context) =>
|
||||||
|
ChangeTpinScreen(mobileNumber: widget.mobileNumber),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// ListTile(
|
// ListTile(
|
||||||
// leading: const Icon(Icons.password),
|
// leading: const Icon(Icons.password),
|
||||||
// title: const Text("Change Login MPIN"),
|
// title: const Text("Change Login MPIN"),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:kmobile/di/injection.dart';
|
import 'package:kmobile/di/injection.dart';
|
||||||
import 'package:kmobile/widgets/pin_input_field.dart';
|
import 'package:kmobile/widgets/pin_input_field.dart';
|
||||||
import '../../../api/services/change_password_service.dart';
|
import '../../../api/services/change_password_service.dart';
|
||||||
|
|
||||||
class ChangeTpinOtpScreen extends StatefulWidget {
|
class ChangeTpinOtpScreen extends StatefulWidget {
|
||||||
final String oldTpin;
|
final String oldTpin;
|
||||||
final String newTpin;
|
final String newTpin;
|
||||||
final String mobileNumber;
|
final String mobileNumber;
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
State<ChangeTpinOtpScreen> createState() => _ChangeTpinOtpScreenState();
|
State<ChangeTpinOtpScreen> createState() => _ChangeTpinOtpScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChangeTpinOtpScreenState extends State<ChangeTpinOtpScreen> {
|
class _ChangeTpinOtpScreenState extends State<ChangeTpinOtpScreen> {
|
||||||
final _otpController = TextEditingController();
|
final _otpController = TextEditingController();
|
||||||
final ChangePasswordService _changePasswordService =
|
final ChangePasswordService _changePasswordService =
|
||||||
getIt<ChangePasswordService>();
|
getIt<ChangePasswordService>();
|
||||||
@@ -122,4 +122,4 @@
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ class _ChangeTpinScreenState extends State<ChangeTpinScreen> {
|
|||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
// 1. Get OTP for TPIN change.
|
// 1. Get OTP for TPIN change.
|
||||||
await _changePasswordService.getOtpTpin(mobileNumber: widget.mobileNumber);
|
await _changePasswordService.getOtpTpin(
|
||||||
|
mobileNumber: widget.mobileNumber);
|
||||||
|
|
||||||
// 2. Navigate to the OTP screen on success.
|
// 2. Navigate to the OTP screen on success.
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ class QuickPayOutsideBankScreen extends StatefulWidget {
|
|||||||
class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
class _QuickPayOutsideBankScreen extends State<QuickPayOutsideBankScreen> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _limitService = getIt<LimitService>();
|
final _limitService = getIt<LimitService>();
|
||||||
Limit? _limit;
|
Limit? _limit;
|
||||||
bool _isLoadingLimit = true;
|
bool _isLoadingLimit = true;
|
||||||
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
||||||
// Controllers
|
// Controllers
|
||||||
final accountNumberController = TextEditingController();
|
final accountNumberController = TextEditingController();
|
||||||
final confirmAccountNumberController = TextEditingController();
|
final confirmAccountNumberController = TextEditingController();
|
||||||
@@ -70,7 +70,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
|||||||
amountController.addListener(_checkAmountLimit);
|
amountController.addListener(_checkAmountLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadLimit() async {
|
Future<void> _loadLimit() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoadingLimit = true;
|
_isLoadingLimit = true;
|
||||||
});
|
});
|
||||||
@@ -86,7 +86,7 @@ Future<void> _loadLimit() async {
|
|||||||
_isLoadingLimit = false;
|
_isLoadingLimit = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add this method to check the amount against the limit
|
// Add this method to check the amount against the limit
|
||||||
void _checkAmountLimit() {
|
void _checkAmountLimit() {
|
||||||
@@ -99,7 +99,8 @@ Future<void> _loadLimit() async {
|
|||||||
if (isOverLimit) {
|
if (isOverLimit) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
content: Text(
|
||||||
|
'Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -783,7 +784,8 @@ Future<void> _loadLimit() async {
|
|||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
isDense: true,
|
isDense: true,
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
fillColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.outline),
|
color: Theme.of(context).colorScheme.outline),
|
||||||
@@ -808,7 +810,8 @@ Future<void> _loadLimit() async {
|
|||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
isDense: true,
|
isDense: true,
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: Theme.of(context).scaffoldBackgroundColor,
|
fillColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.outline),
|
color: Theme.of(context).colorScheme.outline),
|
||||||
@@ -824,7 +827,8 @@ Future<void> _loadLimit() async {
|
|||||||
textInputAction: TextInputAction.next,
|
textInputAction: TextInputAction.next,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return AppLocalizations.of(context).amountRequired;
|
return AppLocalizations.of(context)
|
||||||
|
.amountRequired;
|
||||||
}
|
}
|
||||||
final amount = double.tryParse(value);
|
final amount = double.tryParse(value);
|
||||||
if (amount == null || amount <= 0) {
|
if (amount == null || amount <= 0) {
|
||||||
@@ -839,12 +843,12 @@ Future<void> _loadLimit() async {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (_isLoadingLimit)
|
if (_isLoadingLimit)
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.only(left: 8.0),
|
padding: EdgeInsets.only(left: 8.0),
|
||||||
child: Text('Fetching daily limit...'),
|
child: Text('Fetching daily limit...'),
|
||||||
),
|
),
|
||||||
if (!_isLoadingLimit && _limit != null)
|
if (!_isLoadingLimit && _limit != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -868,9 +872,12 @@ if (!_isLoadingLimit && _limit != null)
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SwipeButton.expand(
|
child: SwipeButton.expand(
|
||||||
thumb: Icon(Icons.arrow_forward,
|
thumb: Icon(Icons.arrow_forward,
|
||||||
color: _isAmountOverLimit ? Colors.grey : Theme.of(context).dialogBackgroundColor),
|
color: _isAmountOverLimit
|
||||||
activeThumbColor: _isAmountOverLimit ? Colors.grey.shade700 :
|
? Colors.grey
|
||||||
Theme.of(context).colorScheme.primary,
|
: Theme.of(context).dialogBackgroundColor),
|
||||||
|
activeThumbColor: _isAmountOverLimit
|
||||||
|
? Colors.grey.shade700
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
activeTrackColor: _isAmountOverLimit
|
activeTrackColor: _isAmountOverLimit
|
||||||
? Colors.grey.shade300
|
? Colors.grey.shade300
|
||||||
: Theme.of(context).colorScheme.secondary.withAlpha(100),
|
: Theme.of(context).colorScheme.secondary.withAlpha(100),
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ class QuickPayWithinBankScreen extends StatefulWidget {
|
|||||||
class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
class _QuickPayWithinBankScreen extends State<QuickPayWithinBankScreen> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _limitService = getIt<LimitService>();
|
final _limitService = getIt<LimitService>();
|
||||||
Limit? _limit;
|
Limit? _limit;
|
||||||
bool _isLoadingLimit = true;
|
bool _isLoadingLimit = true;
|
||||||
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
||||||
final TextEditingController accountNumberController = TextEditingController();
|
final TextEditingController accountNumberController = TextEditingController();
|
||||||
final TextEditingController confirmAccountNumberController =
|
final TextEditingController confirmAccountNumberController =
|
||||||
TextEditingController();
|
TextEditingController();
|
||||||
@@ -46,7 +46,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
|
|||||||
amountController.addListener(_checkAmountLimit);
|
amountController.addListener(_checkAmountLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadLimit() async {
|
Future<void> _loadLimit() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoadingLimit = true;
|
_isLoadingLimit = true;
|
||||||
});
|
});
|
||||||
@@ -62,9 +62,9 @@ Future<void> _loadLimit() async {
|
|||||||
_isLoadingLimit = false;
|
_isLoadingLimit = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkAmountLimit() {
|
void _checkAmountLimit() {
|
||||||
if (_limit == null) return;
|
if (_limit == null) return;
|
||||||
|
|
||||||
final amount = double.tryParse(amountController.text) ?? 0;
|
final amount = double.tryParse(amountController.text) ?? 0;
|
||||||
@@ -74,7 +74,8 @@ void _checkAmountLimit() {
|
|||||||
if (isOverLimit) {
|
if (isOverLimit) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
content: Text(
|
||||||
|
'Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -86,7 +87,7 @@ void _checkAmountLimit() {
|
|||||||
_isAmountOverLimit = isOverLimit;
|
_isAmountOverLimit = isOverLimit;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resetBeneficiaryValidation() {
|
void _resetBeneficiaryValidation() {
|
||||||
if (_isBeneficiaryValidated ||
|
if (_isBeneficiaryValidated ||
|
||||||
@@ -184,7 +185,8 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.primary, width: 2),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
controller: accountNumberController,
|
controller: accountNumberController,
|
||||||
@@ -204,7 +206,8 @@ void _checkAmountLimit() {
|
|||||||
TextFormField(
|
TextFormField(
|
||||||
controller: confirmAccountNumberController,
|
controller: confirmAccountNumberController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: AppLocalizations.of(context).confirmAccountNumber,
|
labelText:
|
||||||
|
AppLocalizations.of(context).confirmAccountNumber,
|
||||||
// prefixIcon: Icon(Icons.person),
|
// prefixIcon: Icon(Icons.person),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
isDense: true,
|
isDense: true,
|
||||||
@@ -216,7 +219,8 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.primary, width: 2),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
@@ -256,10 +260,11 @@ void _checkAmountLimit() {
|
|||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
child:
|
||||||
|
CircularProgressIndicator(strokeWidth: 2),
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(AppLocalizations.of(context)
|
||||||
AppLocalizations.of(context).validateBeneficiary),
|
.validateBeneficiary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -302,7 +307,8 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.primary, width: 2),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
value: _selectedAccountType,
|
value: _selectedAccountType,
|
||||||
@@ -343,12 +349,12 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.primary, width: 2),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
|
|
||||||
TextFormField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: AppLocalizations.of(context).amount,
|
labelText: AppLocalizations.of(context).amount,
|
||||||
@@ -362,7 +368,8 @@ void _checkAmountLimit() {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.primary, width: 2),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
width: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
controller: amountController,
|
controller: amountController,
|
||||||
@@ -380,9 +387,8 @@ void _checkAmountLimit() {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
if (_isLoadingLimit)
|
if (_isLoadingLimit) const Text('Fetching daily limit...'),
|
||||||
const Text('Fetching daily limit...'),
|
if (!_isLoadingLimit && _limit != null)
|
||||||
if (!_isLoadingLimit && _limit != null)
|
|
||||||
Text(
|
Text(
|
||||||
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}',
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
@@ -392,9 +398,12 @@ if (!_isLoadingLimit && _limit != null)
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SwipeButton.expand(
|
child: SwipeButton.expand(
|
||||||
thumb: Icon(Icons.arrow_forward,
|
thumb: Icon(Icons.arrow_forward,
|
||||||
color: _isAmountOverLimit ? Colors.grey : Theme.of(context).dialogBackgroundColor),
|
color: _isAmountOverLimit
|
||||||
activeThumbColor: _isAmountOverLimit ? Colors.grey.shade700 :
|
? Colors.grey
|
||||||
Theme.of(context).colorScheme.primary,
|
: Theme.of(context).dialogBackgroundColor),
|
||||||
|
activeThumbColor: _isAmountOverLimit
|
||||||
|
? Colors.grey.shade700
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
activeTrackColor: _isAmountOverLimit
|
activeTrackColor: _isAmountOverLimit
|
||||||
? Colors.grey.shade300
|
? Colors.grey.shade300
|
||||||
: Theme.of(
|
: Theme.of(
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ void main() async {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Check for device compromise
|
// Check for device compromise
|
||||||
// final compromisedMessage = await SecurityService.deviceCompromisedMessage;
|
final compromisedMessage = await SecurityService.deviceCompromisedMessage;
|
||||||
// if (compromisedMessage != null) {
|
if (compromisedMessage != null) {
|
||||||
// runApp(MaterialApp(
|
runApp(MaterialApp(
|
||||||
// home: SecurityErrorScreen(message: compromisedMessage),
|
home: SecurityErrorScreen(message: compromisedMessage),
|
||||||
// ));
|
));
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
await setupDependencies();
|
await setupDependencies();
|
||||||
runApp(const KMobile());
|
runApp(const KMobile());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TncDialog extends StatefulWidget {
|
class TncDialog extends StatefulWidget {
|
||||||
final Future<void> Function() onProceed;
|
final Future<void> Function() onProceed;
|
||||||
|
|
||||||
const TncDialog({Key? key, required this.onProceed}) : super(key: key);
|
const TncDialog({Key? key, required this.onProceed}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_TncDialogState createState() => _TncDialogState();
|
_TncDialogState createState() => _TncDialogState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TncDialogState extends State<TncDialog> {
|
class _TncDialogState extends State<TncDialog> {
|
||||||
bool _isAgreed = false;
|
bool _isAgreed = false;
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
// --- NEW: ScrollController for the TNC text ---
|
// --- NEW: ScrollController for the TNC text ---
|
||||||
@@ -208,4 +208,4 @@
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user