update gen qr
This commit is contained in:
@@ -17,9 +17,11 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
||||
import 'package:worker/core/constants/ui_constants.dart';
|
||||
import 'package:worker/core/theme/colors.dart';
|
||||
import 'package:worker/features/orders/presentation/providers/order_repository_provider.dart';
|
||||
|
||||
/// Payment QR Page
|
||||
///
|
||||
@@ -28,14 +30,43 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
final String orderId;
|
||||
final double amount;
|
||||
|
||||
const PaymentQrPage({super.key, required this.orderId, required this.amount});
|
||||
const PaymentQrPage({
|
||||
super.key,
|
||||
required this.orderId,
|
||||
required this.amount,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// QR code data state
|
||||
final qrCodeData = useState<Map<String, dynamic>?>(null);
|
||||
final isLoadingQr = useState<bool>(true);
|
||||
final qrError = useState<String?>(null);
|
||||
|
||||
// Countdown timer (15 minutes = 900 seconds)
|
||||
final remainingSeconds = useState<int>(900);
|
||||
final timer = useRef<Timer?>(null);
|
||||
|
||||
// Fetch QR code data
|
||||
useEffect(() {
|
||||
Future<void> fetchQrCode() async {
|
||||
try {
|
||||
isLoadingQr.value = true;
|
||||
qrError.value = null;
|
||||
final repository = await ref.read(orderRepositoryProvider.future);
|
||||
final data = await repository.generateQrCode(orderId);
|
||||
qrCodeData.value = data;
|
||||
} catch (e) {
|
||||
qrError.value = e.toString();
|
||||
} finally {
|
||||
isLoadingQr.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
fetchQrCode();
|
||||
return null;
|
||||
}, [orderId]);
|
||||
|
||||
// Start countdown timer
|
||||
useEffect(() {
|
||||
timer.value = Timer.periodic(const Duration(seconds: 1), (t) {
|
||||
@@ -94,12 +125,24 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// QR Code Card
|
||||
_buildQrCodeCard(amount, orderId),
|
||||
_buildQrCodeCard(
|
||||
amount,
|
||||
orderId,
|
||||
qrCodeData.value?['qr_code'] as String?,
|
||||
isLoadingQr.value,
|
||||
),
|
||||
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// Bank Transfer Info Card
|
||||
_buildBankInfoCard(context, orderId),
|
||||
_buildBankInfoCard(
|
||||
context,
|
||||
orderId,
|
||||
qrCodeData.value?['bank_info']?['bank_name'] as String?,
|
||||
qrCodeData.value?['bank_info']?['account_no'] as String?,
|
||||
qrCodeData.value?['bank_info']?['account_name'] as String?,
|
||||
isLoadingQr.value,
|
||||
),
|
||||
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
@@ -180,14 +223,12 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
/// Build QR code card
|
||||
Widget _buildQrCodeCard(double amount, String orderId) {
|
||||
// Generate QR code data URL
|
||||
final qrData = Uri.encodeComponent(
|
||||
'https://eurotile.com/payment/$orderId?amount=$amount',
|
||||
);
|
||||
final qrUrl =
|
||||
'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=$qrData';
|
||||
|
||||
Widget _buildQrCodeCard(
|
||||
double amount,
|
||||
String orderId,
|
||||
String? qrCodeData,
|
||||
bool isLoading,
|
||||
) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -222,23 +263,29 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
borderRadius: BorderRadius.circular(AppRadius.card),
|
||||
border: Border.all(color: const Color(0xFFE2E8F0)),
|
||||
),
|
||||
child: Image.network(
|
||||
qrUrl,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
FaIcon(FontAwesomeIcons.qrcode, size: 80, color: AppColors.grey500),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
'Không thể tải mã QR',
|
||||
style: TextStyle(fontSize: 12, color: AppColors.grey500),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
child: isLoading
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: qrCodeData != null && qrCodeData.isNotEmpty
|
||||
? QrImageView(
|
||||
data: qrCodeData,
|
||||
version: QrVersions.auto,
|
||||
size: 200.0,
|
||||
backgroundColor: Colors.white,
|
||||
errorCorrectionLevel: QrErrorCorrectLevel.M,
|
||||
)
|
||||
: const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
FaIcon(FontAwesomeIcons.qrcode, size: 80, color: AppColors.grey500),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
'Không thể tải mã QR',
|
||||
style: TextStyle(fontSize: 12, color: AppColors.grey500),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
const Text(
|
||||
@@ -252,7 +299,14 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
/// Build bank transfer info card
|
||||
Widget _buildBankInfoCard(BuildContext context, String orderId) {
|
||||
Widget _buildBankInfoCard(
|
||||
BuildContext context,
|
||||
String orderId,
|
||||
String? bankName,
|
||||
String? accountNo,
|
||||
String? accountName,
|
||||
bool isLoading,
|
||||
) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -281,7 +335,11 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// Bank Name
|
||||
_buildInfoRow(context: context, label: 'Ngân hàng:', value: 'BIDV'),
|
||||
_buildInfoRow(
|
||||
context: context,
|
||||
label: 'Ngân hàng:',
|
||||
value: bankName ?? 'BIDV',
|
||||
),
|
||||
|
||||
const Divider(height: 24),
|
||||
|
||||
@@ -289,7 +347,7 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
_buildInfoRow(
|
||||
context: context,
|
||||
label: 'Số tài khoản:',
|
||||
value: '19036810704016',
|
||||
value: accountNo ?? '19036810704016',
|
||||
),
|
||||
|
||||
const Divider(height: 24),
|
||||
@@ -298,7 +356,7 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
_buildInfoRow(
|
||||
context: context,
|
||||
label: 'Chủ tài khoản:',
|
||||
value: 'CÔNG TY EUROTILE',
|
||||
value: accountName ?? 'CÔNG TY EUROTILE',
|
||||
),
|
||||
|
||||
const Divider(height: 24),
|
||||
@@ -307,7 +365,7 @@ class PaymentQrPage extends HookConsumerWidget {
|
||||
_buildInfoRow(
|
||||
context: context,
|
||||
label: 'Nội dung:',
|
||||
value: '$orderId La Nguyen Quynh',
|
||||
value: orderId,
|
||||
),
|
||||
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
Reference in New Issue
Block a user