updated the look and feel of the home page
This commit is contained in:
@@ -3,15 +3,20 @@ import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:qpay/models/responsive_policy.dart';
|
||||
import 'package:qpay/screens/gateway/gateway_controller.dart';
|
||||
import 'package:qpay/screens/transaction_controller.dart';
|
||||
import 'package:qpay/screens/transaction_controller.dart'
|
||||
show TransactionController;
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:qpay/screens/receipt/receipt_controller.dart';
|
||||
import 'package:qpay/screens/transactions/transaction_model.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:widgets_to_image/widgets_to_image.dart';
|
||||
import 'package:decimal/decimal.dart';
|
||||
|
||||
class ReceiptScreen extends StatefulWidget {
|
||||
const ReceiptScreen({super.key});
|
||||
final String? transactionId;
|
||||
|
||||
const ReceiptScreen({super.key, this.transactionId});
|
||||
|
||||
@override
|
||||
State<ReceiptScreen> createState() => _ReceiptScreenState();
|
||||
@@ -36,6 +41,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
late Animation<double> _contentFadeAnimation;
|
||||
|
||||
int _selectedTabIndex = 0;
|
||||
TransactionModel? _transaction;
|
||||
|
||||
late ReceiptController receiptController;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
@@ -52,9 +58,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
receiptController = ReceiptController(context);
|
||||
gatewayController = GatewayController(context);
|
||||
|
||||
receiptController.getReceiptData(
|
||||
transactionController.model.receiptData?["id"],
|
||||
);
|
||||
_fetchTransaction();
|
||||
|
||||
// Header animation
|
||||
_headerAnimController = AnimationController(
|
||||
@@ -114,6 +118,22 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _fetchTransaction() async {
|
||||
final id =
|
||||
widget.transactionId ??
|
||||
transactionController.model.receiptData?["id"] ??
|
||||
receiptController.model.transaction?.id;
|
||||
|
||||
if (id == null) return;
|
||||
|
||||
final response = await receiptController.getReceiptData(id);
|
||||
if (response.isSuccess && response.data != null) {
|
||||
setState(() {
|
||||
_transaction = response.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _captureImage() async {
|
||||
final image = await controller.capture();
|
||||
if (image != null) {
|
||||
@@ -129,25 +149,21 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
|
||||
_retry() async {
|
||||
receiptController.setLoading(true);
|
||||
await receiptController.doIntegration(
|
||||
receiptController.model.receiptData?["id"],
|
||||
);
|
||||
final id = _transaction?.id ?? '';
|
||||
await receiptController.doIntegration(id);
|
||||
if (receiptController.model.status == "SUCCESS") {
|
||||
receiptController.getReceiptData(
|
||||
receiptController.model.receiptData?["id"],
|
||||
);
|
||||
await _fetchTransaction();
|
||||
}
|
||||
receiptController.setLoading(false);
|
||||
}
|
||||
|
||||
_check() async {
|
||||
receiptController.setLoading(true);
|
||||
await gatewayController.poll(receiptController.model.receiptData?["id"]);
|
||||
final id = _transaction?.id ?? '';
|
||||
await gatewayController.poll(id);
|
||||
if (gatewayController.model.status == "SUCCESS") {
|
||||
receiptController.getReceiptData(
|
||||
transactionController.model.receiptData?["id"],
|
||||
);
|
||||
if (transactionController.model.receiptData?["pollingStatus"]) {
|
||||
await _fetchTransaction();
|
||||
if (_transaction?.pollingStatus == "SUCCESS") {
|
||||
receiptController.setLoading(false);
|
||||
return;
|
||||
}
|
||||
@@ -193,22 +209,10 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
? const Color(0xFF0D0D0D)
|
||||
: const Color(0xFFF8F9FA),
|
||||
leading: context.canPop()
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withValues(
|
||||
alpha: 0.08,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () => context.pop(),
|
||||
icon: const Icon(Icons.arrow_back_rounded),
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
? IconButton(
|
||||
onPressed: () => context.pop(),
|
||||
icon: const Icon(Icons.arrow_back_rounded),
|
||||
color: theme.colorScheme.primary,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
title: Text(
|
||||
@@ -359,13 +363,11 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
// Receipt Header Card
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
Widget _buildReceiptHeader(ThemeData theme, bool isDark) {
|
||||
final status =
|
||||
transactionController.model.receiptData?["integrationStatus"];
|
||||
final amount = receiptController.model.receiptData?["amount"];
|
||||
final currency =
|
||||
receiptController.model.receiptData?["debitCurrency"] ?? "";
|
||||
final billName = receiptController.model.receiptData?["billName"] ?? "";
|
||||
final createdAt = receiptController.model.receiptData?["createdAt"];
|
||||
final status = _transaction?.integrationStatus;
|
||||
final amount = _transaction?.amount;
|
||||
final currency = _transaction?.debitCurrency ?? "";
|
||||
final billName = _transaction?.billName ?? "";
|
||||
final createdAt = _transaction?.createdAt;
|
||||
|
||||
final primaryColor = theme.colorScheme.primary;
|
||||
|
||||
@@ -458,7 +460,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
// Date
|
||||
if (createdAt != null)
|
||||
Text(
|
||||
DateFormat.yMMMd().add_jm().format(DateTime.parse(createdAt)),
|
||||
DateFormat.yMMMd().add_jm().format(createdAt),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -502,9 +504,8 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
// Action Buttons Row
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
Widget _buildActionButtons(ThemeData theme) {
|
||||
final integrationStatus =
|
||||
receiptController.model.receiptData?["integrationStatus"];
|
||||
final paymentStatus = receiptController.model.receiptData?["paymentStatus"];
|
||||
final integrationStatus = _transaction?.integrationStatus;
|
||||
final paymentStatus = _transaction?.paymentStatus;
|
||||
|
||||
return Wrap(
|
||||
spacing: 12,
|
||||
@@ -516,7 +517,14 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
label: "Repeat",
|
||||
color: theme.colorScheme.primary,
|
||||
isLoading: receiptController.model.isLoading,
|
||||
onPressed: () => receiptController.repeatTransaction(context),
|
||||
onPressed: () async {
|
||||
await receiptController.repeatTransaction(
|
||||
receiptController.model.transaction!,
|
||||
);
|
||||
if (mounted) {
|
||||
context.push('/make-payment');
|
||||
}
|
||||
},
|
||||
),
|
||||
_modernActionButton(
|
||||
icon: Icons.ios_share_rounded,
|
||||
@@ -534,8 +542,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
onPressed: _retry,
|
||||
),
|
||||
],
|
||||
if (receiptController.model.receiptData?["pollingStatus"] !=
|
||||
"SUCCESS") ...[
|
||||
if (_transaction?.pollingStatus != "SUCCESS") ...[
|
||||
_modernActionButton(
|
||||
icon: Icons.search_rounded,
|
||||
label: "Check",
|
||||
@@ -705,8 +712,8 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
// Provider Details Tab
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
Widget _buildProviderDetailsTab(ThemeData theme, bool isDark) {
|
||||
final receiptData = receiptController.model.receiptData;
|
||||
final additionalData = receiptData?["additionalData"];
|
||||
final receiptData = receiptController.model.transaction;
|
||||
final additionalData = receiptData?.additionalData;
|
||||
|
||||
final items = <_DetailItem>[];
|
||||
|
||||
@@ -715,14 +722,13 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
_DetailItem(
|
||||
icon: Icons.circle_outlined,
|
||||
label: "Status",
|
||||
value:
|
||||
transactionController.model.receiptData?["integrationStatus"] ?? "",
|
||||
value: _transaction?.integrationStatus ?? "",
|
||||
),
|
||||
);
|
||||
|
||||
// Error message
|
||||
final errorMsg = transactionController.model.receiptData?["errorMessage"];
|
||||
if (errorMsg != null && errorMsg != "") {
|
||||
final errorMsg = _transaction?.errorMessage;
|
||||
if (errorMsg != null && errorMsg.isNotEmpty) {
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.warning_amber_rounded,
|
||||
@@ -751,37 +757,37 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
_DetailItem(
|
||||
icon: Icons.tag_rounded,
|
||||
label: "Debit Reference",
|
||||
value: transactionController.model.receiptData?["debitRef"] ?? "",
|
||||
value: _transaction?.debitRef ?? "",
|
||||
),
|
||||
);
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.phone_iphone_rounded,
|
||||
label: "From",
|
||||
value: receiptData?["debitPhone"] ?? "",
|
||||
value: receiptData?.debitPhone ?? "",
|
||||
),
|
||||
);
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.account_balance_wallet_rounded,
|
||||
label: "To",
|
||||
value: receiptData?["creditAccount"] ?? "",
|
||||
value: receiptData?.creditAccount ?? "",
|
||||
),
|
||||
);
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.memory_rounded,
|
||||
label: "Processor",
|
||||
value: receiptData?["paymentProcessorName"] ?? "",
|
||||
value: receiptData?.paymentProcessorName ?? "",
|
||||
),
|
||||
);
|
||||
|
||||
if (receiptData?["billProductName"] != null) {
|
||||
if (receiptData?.billProductName != null) {
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.category_rounded,
|
||||
label: "Bill Product",
|
||||
value: receiptData?["billProductName"] ?? "",
|
||||
value: receiptData?.billProductName ?? "",
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -822,12 +828,12 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
// Transaction Details Tab
|
||||
// ──────────────────────────────────────────────────────────────
|
||||
Widget _buildTransactionDetailsTab(ThemeData theme, bool isDark) {
|
||||
final receiptData = transactionController.model.receiptData;
|
||||
final amount = receiptData?["amount"] ?? 0;
|
||||
final charge = receiptData?["charge"] ?? 0;
|
||||
final gatewayCharge = receiptData?["gatewayCharge"] ?? 0;
|
||||
final tax = receiptData?["tax"] ?? 0;
|
||||
final totalAmount = receiptData?["totalAmount"] ?? 0;
|
||||
final t = _transaction;
|
||||
final amount = t?.amount ?? Decimal.zero;
|
||||
final charge = t?.charge ?? Decimal.zero;
|
||||
final gatewayCharge = t?.gatewayCharge ?? Decimal.zero;
|
||||
final tax = t?.tax ?? Decimal.zero;
|
||||
final totalAmount = t?.totalAmount ?? Decimal.zero;
|
||||
|
||||
final items = <_DetailItem>[
|
||||
_DetailItem(
|
||||
@@ -842,7 +848,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
),
|
||||
];
|
||||
|
||||
if (charge != 0) {
|
||||
if (charge != Decimal.zero) {
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.percent_rounded,
|
||||
@@ -851,7 +857,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
),
|
||||
);
|
||||
}
|
||||
if (gatewayCharge != 0) {
|
||||
if (gatewayCharge != Decimal.zero) {
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.account_balance_rounded,
|
||||
@@ -860,7 +866,7 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
||||
),
|
||||
);
|
||||
}
|
||||
if (tax != 0) {
|
||||
if (tax != Decimal.zero) {
|
||||
items.add(
|
||||
_DetailItem(
|
||||
icon: Icons.receipt_rounded,
|
||||
|
||||
Reference in New Issue
Block a user