Transaction Details page

This commit is contained in:
2025-08-12 18:10:02 +05:30
parent 7f5258b5b7
commit 913e31a6ab
6 changed files with 206 additions and 47 deletions

View File

@@ -6,6 +6,7 @@ import 'package:kmobile/data/models/transaction.dart';
import 'package:kmobile/data/repositories/transaction_repository.dart';
import 'package:kmobile/di/injection.dart';
import '../../../l10n/app_localizations.dart';
import 'transaction_details_screen.dart';
class AccountStatementScreen extends StatefulWidget {
final String accountNo;
@@ -289,6 +290,15 @@ class _AccountStatementScreen extends State<AccountStatementScreen> {
"${tx.amount}",
style: const TextStyle(fontSize: 16),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
TransactionDetailsScreen(transaction: tx),
),
);
},
);
},
),

View File

@@ -0,0 +1,160 @@
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
class TransactionDetailsScreen extends StatelessWidget {
final dynamic transaction;
const TransactionDetailsScreen({super.key, required this.transaction});
@override
Widget build(BuildContext context) {
final bool isCredit = transaction.type?.toUpperCase() == 'CR';
// Future<void> _shareScreenshot() async {
// try {
// RenderRepaintBoundary boundary =
// _shareKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
// ui.Image image = await boundary.toImage(pixelRatio: 3.0);
// ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
// Uint8List pngBytes = byteData!.buffer.asUint8List();
// final tempDir = await getTemporaryDirectory();
// final file = await File('${tempDir.path}/payment_result.png').create();
// await file.writeAsBytes(pngBytes);
// await Share.shareXFiles(
// [XFile(file.path)],
// text: AppLocalizations.of(context).paymentResult,
// );
// } catch (e) {
// if (!mounted) return;
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(
// '${AppLocalizations.of(context).failedToShareScreenshot}: $e',
// ),
// ),
// );
// }
// }
return Scaffold(
appBar: AppBar(title: const Text("Transaction Details")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// Absolute center for amount + icon + date + details + share button
Expanded(
flex: 3,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Amount + icon + Share Button
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"${transaction.amount}",
style: const TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 8),
Icon(
isCredit ? Symbols.call_received : Symbols.call_made,
color: isCredit ? Colors.green : Colors.red,
size: 28,
),
],
),
const SizedBox(height: 8),
// Date centered
Text(
transaction.date ?? "",
style: const TextStyle(
fontSize: 16,
color: Colors.grey,
),
textAlign: TextAlign.center,
),
],
),
),
),
const Divider(),
// All details
Expanded(
flex: 5,
child: ListView(
children: [
_buildDetailRow("Transaction Type", transaction.type ?? ""),
_buildDetailRow("Transfer Type", transaction.name.split("/").first ?? ""),
if(transaction.name.length> 12) ... [
_buildDetailRow("UTR No", transaction.name.split("= ")[1].split(" ")[0] ?? ""),
_buildDetailRow("Beneficiary Account No", transaction.name.split("A/C ").last ?? "")
]
],
),
),
// ElevatedButton.icon(
// onPressed: _shareScreenshot,
// icon: Icon(
// Icons.share_rounded,
// color: Theme.of(context).primaryColor,
// ),
// label: Text(
// AppLocalizations.of(context).share,
// style: TextStyle(color: Theme.of(context).primaryColor),
// ),
// style: ElevatedButton.styleFrom(
// backgroundColor: Theme.of(context).scaffoldBackgroundColor,
// padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
// shape: RoundedRectangleBorder(
// side: BorderSide(color: Theme.of(context).primaryColor, width: 1),
// borderRadius: BorderRadius.circular(30),
// ),
// textStyle: const TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.w600,
// color: Colors.black,
// ),
// ),
// ),
],
),
),
);
}
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"$label: ",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
const SizedBox(height: 30),
Expanded(
child: Text(
value,
style: const TextStyle(fontSize: 20),
),
),
],
),
);
}
}

View File

@@ -1,5 +1,4 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -8,6 +7,7 @@ import 'package:kmobile/data/repositories/transaction_repository.dart';
import 'package:kmobile/di/injection.dart';
import 'package:kmobile/features/accounts/screens/account_info_screen.dart';
import 'package:kmobile/features/accounts/screens/account_statement_screen.dart';
import 'package:kmobile/features/accounts/screens/transaction_details_screen.dart';
import 'package:kmobile/features/auth/controllers/auth_cubit.dart';
import 'package:kmobile/features/auth/controllers/auth_state.dart';
import 'package:kmobile/features/customer_info/screens/customer_info_screen.dart';
@@ -581,6 +581,15 @@ class _DashboardScreenState extends State<DashboardScreen> {
"${tx.amount}",
style: const TextStyle(fontSize: 16),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
TransactionDetailsScreen(transaction: tx),
),
);
},
),
)
else

View File

@@ -62,8 +62,7 @@ import 'app_localizations_hi.dart';
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
@@ -71,8 +70,7 @@ abstract class 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
/// delegates.
@@ -84,8 +82,7 @@ abstract class AppLocalizations {
/// 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
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
@@ -1419,8 +1416,7 @@ abstract class AppLocalizations {
String get themeMode;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
@@ -1429,25 +1425,25 @@ class _AppLocalizationsDelegate
}
@override
bool isSupported(Locale locale) =>
<String>['en', 'hi'].contains(locale.languageCode);
bool isSupported(Locale locale) => <String>['en', 'hi'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
case 'hi':
return AppLocalizationsHi();
case 'en': return AppLocalizationsEn();
case 'hi': return AppLocalizationsHi();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.'
);
}

View File

@@ -1,5 +1,3 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -488,8 +486,7 @@ class AppLocalizationsEn extends AppLocalizations {
String get otpVerification => 'OTP Verification';
@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
String get verifyOtp => 'Verify OTP';
@@ -507,15 +504,13 @@ class AppLocalizationsEn extends AppLocalizations {
String get tpinRequired => 'TPIN Required';
@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
String get setTpinTitle => 'Set TPIN';
@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
String get tpinFailed => 'Failed to set TPIN. Please try again.';
@@ -569,8 +564,7 @@ class AppLocalizationsEn extends AppLocalizations {
String get enableFingerprintLogin => 'Enable Fingerprint Login?';
@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
String get no => 'No';
@@ -591,8 +585,7 @@ class AppLocalizationsEn extends AppLocalizations {
String get loading => 'Loading......';
@override
String get enableFingerprintQuick =>
'Enable fingerprint authentication for quick login?';
String get enableFingerprintQuick => 'Enable fingerprint authentication for quick login?';
@override
String get kccb => 'KCCB';

View File

@@ -1,5 +1,3 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
@@ -54,8 +52,7 @@ class AppLocalizationsHi extends AppLocalizations {
String get enableBiometric => 'बायोमेट्रिक प्रमाणीकरण सक्षम करें';
@override
String get useBiometricPrompt =>
'तेज़ लॉगिन के लिए फिंगरप्रिंट/फेस आईडी का उपयोग करें?';
String get useBiometricPrompt => 'तेज़ लॉगिन के लिए फिंगरप्रिंट/फेस आईडी का उपयोग करें?';
@override
String get later => 'बाद में';
@@ -489,8 +486,7 @@ class AppLocalizationsHi extends AppLocalizations {
String get otpVerification => 'ओटीपी सत्यापन';
@override
String get otpSentMessage =>
'अपने मोबाइल नंबर पर भेजा गया 4-अंकों का ओटीपी दर्ज करें';
String get otpSentMessage => 'अपने मोबाइल नंबर पर भेजा गया 4-अंकों का ओटीपी दर्ज करें';
@override
String get verifyOtp => 'ओटीपी सत्यापित करें';
@@ -508,15 +504,13 @@ class AppLocalizationsHi extends AppLocalizations {
String get tpinRequired => 'टी-पिन आवश्यक है';
@override
String get tpinRequiredMessage =>
'सुरक्षित लेनदेन के लिए टी-पिन सेट करना आवश्यक है';
String get tpinRequiredMessage => 'सुरक्षित लेनदेन के लिए टी-पिन सेट करना आवश्यक है';
@override
String get setTpinTitle => 'टी-पिन सेट करें';
@override
String get tpinInfo =>
'आपका टी-पिन 6 अंकों का कोड है जिसका उपयोग लेन-देन को प्रमाणित करने के लिए किया जाता है। इसे सुरक्षित रखें और किसी से साझा न करें।';
String get tpinInfo => 'आपका टी-पिन 6 अंकों का कोड है जिसका उपयोग लेन-देन को प्रमाणित करने के लिए किया जाता है। इसे सुरक्षित रखें और किसी से साझा न करें।';
@override
String get tpinFailed => 'टी-पिन सेट करने में विफल। कृपया पुनः प्रयास करें।';
@@ -570,8 +564,7 @@ class AppLocalizationsHi extends AppLocalizations {
String get enableFingerprintLogin => 'फिंगरप्रिंट लॉगिन सक्षम करें?';
@override
String get enableFingerprintMessage =>
'क्या आप तेज लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करना चाहेंगे?';
String get enableFingerprintMessage => 'क्या आप तेज लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करना चाहेंगे?';
@override
String get no => 'नहीं';
@@ -580,8 +573,7 @@ class AppLocalizationsHi extends AppLocalizations {
String get yes => 'हाँ';
@override
String get authenticateToEnable =>
'फिंगरप्रिंट लॉगिन सक्षम करने के लिए प्रमाणीकरण करें';
String get authenticateToEnable => 'फिंगरप्रिंट लॉगिन सक्षम करने के लिए प्रमाणीकरण करें';
@override
String get exitApp => 'ऐप बंद करें';
@@ -593,8 +585,7 @@ class AppLocalizationsHi extends AppLocalizations {
String get loading => 'लोड हो रहा है......';
@override
String get enableFingerprintQuick =>
'तेज़ लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करें?';
String get enableFingerprintQuick => 'तेज़ लॉगिन के लिए फिंगरप्रिंट प्रमाणीकरण सक्षम करें?';
@override
String get kccb => 'केसीसीबी';