26-1-21/1

This commit is contained in:
Hamza-Ayed
2026-01-21 17:01:45 +03:00
parent 11dfe94bbb
commit 3e89e1f1f0
32 changed files with 101957 additions and 12193 deletions

View File

@@ -151,8 +151,8 @@ void showPaymentBottomSheet(BuildContext context) {
_buildPaymentOption(
context: context,
controller: controller,
amount: 10000,
bonusAmount: 0,
amount: 500,
bonusAmount: 30,
currency: 'SYP'.tr,
),
@@ -160,8 +160,8 @@ void showPaymentBottomSheet(BuildContext context) {
_buildPaymentOption(
context: context,
controller: controller,
amount: 20000,
bonusAmount: 500,
amount: 1000,
bonusAmount: 70,
currency: 'SYP'.tr,
),
@@ -169,8 +169,8 @@ void showPaymentBottomSheet(BuildContext context) {
_buildPaymentOption(
context: context,
controller: controller,
amount: 40000,
bonusAmount: 2500,
amount: 2000,
bonusAmount: 180,
currency: 'SYP'.tr,
),
@@ -178,8 +178,8 @@ void showPaymentBottomSheet(BuildContext context) {
_buildPaymentOption(
context: context,
controller: controller,
amount: 100000,
bonusAmount: 4000,
amount: 5000,
bonusAmount: 700,
currency: 'SYP'.tr,
),
@@ -466,18 +466,24 @@ void showPaymentOptions(BuildContext context, PaymentController controller) {
Get.to(() => PaymentScreenSmsProvider(
amount: double.parse(controller.selectedAmount.toString())));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Pay by Sham Cash'.tr),
const SizedBox(width: 10),
Image.asset(
'assets/images/shamCash.png',
width: 70,
height: 70,
fit: BoxFit.fill,
),
],
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Pay by Sham Cash'.tr,
style: AppStyle.title,
),
const SizedBox(width: 10),
Image.asset(
'assets/images/shamCash.png',
width: 70,
height: 70,
fit: BoxFit.fill,
),
],
),
)),
],
cancelButton: CupertinoActionSheetAction(

View File

@@ -8,9 +8,8 @@ import '../../../constant/links.dart';
import '../../../controller/functions/crud.dart';
import '../../../main.dart';
// خدمة الدفع للراكب (تم تحديث المسارات)
// --- خدمة الدفع (نفس المنطق السابق) ---
class PaymentService {
// المسار الجديد لمجلد الركاب
final String _baseUrl = "${AppLink.paymentServer}/ride/shamcash/passenger";
Future<String?> createInvoice({required double amount}) async {
@@ -19,7 +18,7 @@ class PaymentService {
final response = await CRUD().postWallet(
link: url,
payload: {
'passengerID': box.read(BoxName.passengerID), // استخدام passengerID
'passengerID': box.read(BoxName.passengerID),
'amount': amount.toString(),
},
).timeout(const Duration(seconds: 15));
@@ -83,21 +82,46 @@ class PaymentScreenSmsProvider extends StatefulWidget {
_PaymentScreenSmsProviderState();
}
class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider>
with SingleTickerProviderStateMixin {
final PaymentService _paymentService = PaymentService();
Timer? _pollingTimer;
PaymentStatus _status = PaymentStatus.creatingInvoice;
String? _invoiceNumber;
// العنوان الثابت للدفع (المستخرج من الصورة)
final String _paymentAddress = "80f23afe40499b02f49966c3340ae0fc";
// متحكم الأنيميشن للوميض
late AnimationController _blinkController;
late Animation<Color?> _colorAnimation;
late Animation<double> _shadowAnimation;
@override
void initState() {
super.initState();
// إعداد الأنيميشن (وميض أحمر)
_blinkController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
)..repeat(reverse: true); // يكرر الحركة ذهاباً وإياباً
_colorAnimation = ColorTween(
begin: Colors.red.shade700,
end: Colors.red.shade100,
).animate(_blinkController);
_shadowAnimation = Tween<double>(begin: 2.0, end: 15.0).animate(
CurvedAnimation(parent: _blinkController, curve: Curves.easeInOut),
);
_createAndPollInvoice();
}
@override
void dispose() {
_pollingTimer?.cancel();
_blinkController.dispose();
super.dispose();
}
@@ -216,7 +240,7 @@ class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
// 1. المبلغ
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 15),
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue.shade800, Colors.blue.shade600]),
@@ -224,97 +248,166 @@ class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
boxShadow: [
BoxShadow(
color: Colors.blue.withOpacity(0.25),
blurRadius: 15,
offset: const Offset(0, 8))
blurRadius: 10,
offset: const Offset(0, 5))
],
),
child: Column(
children: [
const Text("المبلغ المطلوب",
style: TextStyle(color: Colors.white70, fontSize: 14)),
const SizedBox(height: 8),
const SizedBox(height: 5),
Text("${currencyFormat.format(widget.amount)} ل.س",
style: const TextStyle(
color: Colors.white,
fontSize: 32,
fontSize: 28,
fontWeight: FontWeight.bold)),
],
),
),
const SizedBox(height: 30),
const SizedBox(height: 25),
// 2. التعليمات والنسخ (للراكب)
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey.shade200),
boxShadow: [
BoxShadow(
color: Colors.grey.shade100,
blurRadius: 10,
offset: const Offset(0, 4))
],
),
child: Column(
children: [
Row(
// 2. رقم البيان (هام جداً - وميض أحمر)
AnimatedBuilder(
animation: _blinkController,
builder: (context, child) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: _colorAnimation.value ?? Colors.red,
width: 3.0, // إطار سميك
),
boxShadow: [
BoxShadow(
color: (_colorAnimation.value ?? Colors.red)
.withOpacity(0.4),
blurRadius: _shadowAnimation.value,
spreadRadius: 2,
)
],
),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.orange.shade50, shape: BoxShape.circle),
child: Icon(Icons.priority_high_rounded,
color: Colors.orange.shade800, size: 20),
),
const SizedBox(width: 12),
const Expanded(
child: Text(
"انسخ الرقم أدناه وضعه في خانة (الملاحظات) عند الدفع.",
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.warning_rounded,
color: Colors.red.shade800, size: 28),
const SizedBox(width: 8),
Text(
"هام جداً: لا تنسَ!",
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.w600)),
color: Colors.red.shade900,
fontWeight: FontWeight.bold,
fontSize: 18),
),
],
),
const SizedBox(height: 10),
const Text(
"يجب نسخ (رقم البيان) هذا ووضعه في تطبيق شام كاش لضمان نجاح العملية.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Colors.black87,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 15),
InkWell(
onTap: () {
Clipboard.setData(ClipboardData(text: invoiceText));
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text("تم نسخ رقم البيان ✅",
textAlign: TextAlign.center),
backgroundColor: Colors.red.shade700));
},
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 12),
decoration: BoxDecoration(
color: Colors.red.shade50,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.red.shade200, width: 1)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("رقم البيان (Invoice No)",
style: TextStyle(
fontSize: 12, color: Colors.grey)),
Text(invoiceText,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
letterSpacing: 2.0,
color: Colors.red.shade900)),
],
),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.red.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Icon(Icons.copy_rounded,
color: Colors.red.shade900, size: 24),
),
],
),
),
),
],
),
const SizedBox(height: 20),
);
},
),
const SizedBox(height: 25),
// 3. عنوان الدفع (اختياري / عادي)
Container(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("عنوان الدفع (Payment Address)",
style: TextStyle(fontSize: 12, color: Colors.grey)),
const SizedBox(height: 8),
InkWell(
onTap: () {
Clipboard.setData(ClipboardData(text: invoiceText));
Clipboard.setData(ClipboardData(text: _paymentAddress));
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text("تم نسخ رقم البيان",
content: const Text("تم نسخ عنوان الدفع",
textAlign: TextAlign.center),
backgroundColor: Colors.green.shade600));
},
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 12),
decoration: BoxDecoration(
color: Colors.grey.shade50,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.blue.shade200, width: 1.5)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("رقم البيان (Invoice ID)",
style: TextStyle(
fontSize: 12, color: Colors.grey)),
Text(invoiceText,
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
letterSpacing: 1.5)),
],
),
const Icon(Icons.copy_rounded,
color: Colors.blue, size: 24),
],
),
child: Row(
children: [
Expanded(
child: Text(_paymentAddress,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
fontFamily: 'Courier',
color: Colors.black87,
),
overflow: TextOverflow.ellipsis),
),
const SizedBox(width: 8),
const Icon(Icons.copy, size: 18, color: Colors.grey),
],
),
),
],
@@ -322,10 +415,10 @@ class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
),
const SizedBox(height: 30),
// 3. QR Code
const Text("امسح الرمز للدفع",
// 4. QR Code
const Text("أو امسح الرمز للدفع",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 15),
const SizedBox(height: 10),
GestureDetector(
onTap: () {
showDialog(
@@ -336,30 +429,23 @@ class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
child: Image.asset(widget.qrImagePath))));
},
child: Container(
padding: const EdgeInsets.all(15),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.grey.shade300)),
child: Column(
children: [
Image.asset(widget.qrImagePath,
width: 180,
height: 180,
fit: BoxFit.contain,
errorBuilder: (c, o, s) => const Icon(Icons.qr_code_2,
size: 100, color: Colors.grey)),
const SizedBox(height: 8),
const Text("اضغط للتكبير",
style: TextStyle(fontSize: 10, color: Colors.grey)),
],
),
child: Image.asset(widget.qrImagePath,
width: 150,
height: 150,
fit: BoxFit.contain,
errorBuilder: (c, o, s) => const Icon(Icons.qr_code_2,
size: 100, color: Colors.grey)),
),
),
const SizedBox(height: 40),
const SizedBox(height: 30),
const LinearProgressIndicator(backgroundColor: Colors.white),
const SizedBox(height: 10),
const Text("ننتظر إشعار الدفع تلقائياً...",
const Text("جاري التحقق من الدفع تلقائياً...",
style: TextStyle(color: Colors.grey, fontSize: 12)),
const SizedBox(height: 20),
],
@@ -405,7 +491,7 @@ class _PaymentScreenSmsProviderState extends State<PaymentScreenSmsProvider> {
const SizedBox(height: 15),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Text("لم يصلنا إشعار الدفع.",
child: Text("لم يصلنا إشعار الدفع خلال الوقت المحدد.",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey))),
const SizedBox(height: 40),