Update: 2026-05-17 18:47:51

This commit is contained in:
Hamza-Ayed
2026-05-17 18:47:51 +03:00
parent 9ad361e992
commit 2f1a6f9c85
6 changed files with 199 additions and 110 deletions

View File

@@ -254,14 +254,16 @@ class DashboardView extends GetView<DashboardController> {
isDark, isDark,
() => Get.toNamed(AppRoutes.AUDIT_LOG), () => Get.toNamed(AppRoutes.AUDIT_LOG),
), ),
const SizedBox(width: 12), if (!GetPlatform.isIOS) ...[
_buildAdminActionCard( const SizedBox(width: 12),
'ادعُ واكسب', _buildAdminActionCard(
Icons.card_giftcard, 'ادعُ واكسب',
const Color(0xFFD4AF37), Icons.card_giftcard,
isDark, const Color(0xFFD4AF37),
() => Get.toNamed(AppRoutes.REFERRAL), isDark,
), () => Get.toNamed(AppRoutes.REFERRAL),
),
],
const SizedBox(width: 12), const SizedBox(width: 12),
_buildAdminActionCard( _buildAdminActionCard(
'استهلاك AI', 'استهلاك AI',

View File

@@ -5,7 +5,7 @@ import '../../../app/routes/app_pages.dart';
class OnboardingController extends GetxController { class OnboardingController extends GetxController {
var currentPage = 0.obs; var currentPage = 0.obs;
final List<OnboardingModel> items = [ List<OnboardingModel> get items => [
OnboardingModel( OnboardingModel(
title: 'مرحباً بك في مُصادَق', title: 'مرحباً بك في مُصادَق',
description: description:
@@ -19,9 +19,10 @@ class OnboardingController extends GetxController {
imageAsset: 'assets/images/onboarding_2.png', imageAsset: 'assets/images/onboarding_2.png',
), ),
OnboardingModel( OnboardingModel(
title: 'مدفوعات فورية آمنة', title: 'إدارة متكاملة لشركتك',
description: description: GetPlatform.isIOS
'قم بشحن محفظتك وتفعيل اشتراكك عبر نظام كليك (CliQ) بكل سرعة وأمان.', ? 'إدارة فواتير الشركات وأرشفة ضريبية متكاملة بأمان وسهولة تامة.'
: 'قم بشحن محفظتك وتفعيل اشتراكك عبر نظام كليك (CliQ) بكل سرعة وأمان.',
imageAsset: 'assets/images/onboarding_3.png', imageAsset: 'assets/images/onboarding_3.png',
), ),
]; ];

View File

@@ -166,7 +166,7 @@ class SettingsView extends GetView<SettingsController> {
_buildInfoTile( _buildInfoTile(
icon: Icons.diamond_rounded, icon: Icons.diamond_rounded,
title: 'الاشتراكات والباقات', title: 'الاشتراكات والباقات',
trailing: 'ترقية →', trailing: GetPlatform.isIOS ? 'التفاصيل →' : 'ترقية →',
isDark: isDark, isDark: isDark,
onTap: () => Get.toNamed(AppRoutes.SUBSCRIPTION), onTap: () => Get.toNamed(AppRoutes.SUBSCRIPTION),
), ),

View File

@@ -34,114 +34,122 @@ class SubscriptionView extends StatelessWidget {
children: [ children: [
// Current Subscription Status // Current Subscription Status
if (controller.currentSubscription.value != null) if (controller.currentSubscription.value != null)
_buildCurrentPlan(controller.currentSubscription.value!, isDark), _buildCurrentPlan(controller.currentSubscription.value!, isDark)
else
_buildFreePlanPlaceholder(isDark),
const SizedBox(height: 24), const SizedBox(height: 24),
// Active Payment Request Banner if (GetPlatform.isIOS) ...[
if (controller.activePaymentRequest.value != null) _buildIOSB2BInfoCard(isDark),
_buildActivePaymentBanner(controller.activePaymentRequest.value!, isDark), ],
// Plans Header if (!GetPlatform.isIOS) ...[
Row( // Active Payment Request Banner
mainAxisAlignment: MainAxisAlignment.spaceBetween, if (controller.activePaymentRequest.value != null)
children: [ _buildActivePaymentBanner(controller.activePaymentRequest.value!, isDark),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.diamond_rounded, color: Color(0xFFD4AF37), size: 22),
const SizedBox(width: 8),
Text(
'اختر باقتك',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: isDark ? Colors.white : const Color(0xFF0F172A),
),
),
],
),
const SizedBox(height: 4),
Text(
'ادفع عبر CliQ — بدون عمولة!',
style: TextStyle(fontSize: 13, color: isDark ? Colors.white38 : Colors.grey),
),
],
),
],
),
const SizedBox(height: 20),
// Toggle // Plans Header
Container( Row(
padding: const EdgeInsets.all(4), mainAxisAlignment: MainAxisAlignment.spaceBetween,
decoration: BoxDecoration(
color: isDark ? Colors.white.withOpacity(0.05) : Colors.black.withOpacity(0.05),
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [ children: [
Expanded( Column(
child: GestureDetector( crossAxisAlignment: CrossAxisAlignment.start,
onTap: () => controller.isAnnual.value = false, children: [
child: Obx(() => Container( Row(
padding: const EdgeInsets.symmetric(vertical: 10), children: [
decoration: BoxDecoration( const Icon(Icons.diamond_rounded, color: Color(0xFFD4AF37), size: 22),
color: !controller.isAnnual.value ? const Color(0xFF0F4C81) : Colors.transparent, const SizedBox(width: 8),
borderRadius: BorderRadius.circular(10), Text(
), 'اختر باقتك',
child: Center(
child: Text(
'دفع شهري',
style: TextStyle( style: TextStyle(
color: !controller.isAnnual.value ? Colors.white : (isDark ? Colors.white60 : Colors.black54), fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 13, color: isDark ? Colors.white : const Color(0xFF0F172A),
), ),
), ),
), ],
)), ),
), const SizedBox(height: 4),
), Text(
Expanded( 'ادفع عبر CliQ — بدون عمولة!',
child: GestureDetector( style: TextStyle(fontSize: 13, color: isDark ? Colors.white38 : Colors.grey),
onTap: () => controller.isAnnual.value = true, ),
child: Obx(() => Container( ],
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: controller.isAnnual.value ? const Color(0xFF0F4C81) : Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
'دفع سنوي (توفير ✨)',
style: TextStyle(
color: controller.isAnnual.value ? Colors.white : (isDark ? Colors.white60 : Colors.black54),
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
),
)),
),
), ),
], ],
), ),
), const SizedBox(height: 20),
const SizedBox(height: 20),
// Plans Grid // Toggle
...controller.plans.map((plan) => _buildPlanCard(plan, controller, isDark)), Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
color: isDark ? Colors.white.withOpacity(0.05) : Colors.black.withOpacity(0.05),
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Expanded(
child: GestureDetector(
onTap: () => controller.isAnnual.value = false,
child: Obx(() => Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: !controller.isAnnual.value ? const Color(0xFF0F4C81) : Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
'دفع شهري',
style: TextStyle(
color: !controller.isAnnual.value ? Colors.white : (isDark ? Colors.white60 : Colors.black54),
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
),
)),
),
),
Expanded(
child: GestureDetector(
onTap: () => controller.isAnnual.value = true,
child: Obx(() => Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: controller.isAnnual.value ? const Color(0xFF0F4C81) : Colors.transparent,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
'دفع سنوي (توفير ✨)',
style: TextStyle(
color: controller.isAnnual.value ? Colors.white : (isDark ? Colors.white60 : Colors.black54),
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
),
)),
),
),
],
),
),
const SizedBox(height: 20),
const SizedBox(height: 24), // Plans Grid
...controller.plans.map((plan) => _buildPlanCard(plan, controller, isDark)),
// Payment History const SizedBox(height: 24),
if (controller.myPayments.isNotEmpty) ...[
const Text('سجل المدفوعات', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), // Payment History
const SizedBox(height: 12), if (controller.myPayments.isNotEmpty) ...[
...controller.myPayments.map((p) => _buildPaymentHistoryItem(p, isDark)), const Text('سجل المدفوعات', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 12),
...controller.myPayments.map((p) => _buildPaymentHistoryItem(p, isDark)),
],
], ],
const SizedBox(height: 40), const SizedBox(height: 40),
@@ -153,6 +161,84 @@ class SubscriptionView extends StatelessWidget {
); );
} }
Widget _buildFreePlanPlaceholder(bool isDark) {
return _buildCurrentPlan({
'plan_name': 'الباقة الافتراضية (المجانية)',
'days_remaining': 0,
'invoices': {
'used': 0,
'limit': 100,
}
}, isDark);
}
Widget _buildIOSB2BInfoCard(bool isDark) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF1E1E2E) : Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: isDark ? Colors.white10 : Colors.grey.shade200,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.business_rounded, color: const Color(0xFF0F4C81), size: 24),
const SizedBox(width: 8),
Text(
'الاشتراكات المؤسسية (B2B)',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: isDark ? Colors.white : const Color(0xFF0F172A),
),
),
],
),
const SizedBox(height: 12),
Text(
'تطبيق "مُصادَق" مخصص لإدارة الفواتير الضريبية للشركات ومكاتب المحاسبة. يتم تفعيل وإدارة باقات الاشتراك والميزات الإضافية مركزياً عن طريق لوحة التحكم الخاصة بالمسؤول في منشأتك.',
style: TextStyle(
fontSize: 13,
height: 1.5,
color: isDark ? Colors.white70 : Colors.black87,
),
),
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFF0F4C81).withOpacity(0.05),
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
Icon(Icons.info_outline, color: const Color(0xFF0F4C81), size: 20),
const SizedBox(width: 10),
Expanded(
child: Text(
'إذا كنت بحاجة إلى ترقية باقتك أو زيادة الحصص (Quotas)، يرجى التواصل مع مسؤول تكنولوجيا المعلومات أو المحاسب المسؤول في شركتك.',
style: TextStyle(
fontSize: 12,
height: 1.4,
color: const Color(0xFF0F4C81),
fontWeight: FontWeight.w600,
),
),
),
],
),
),
],
),
);
}
Widget _buildCurrentPlan(Map<String, dynamic> sub, bool isDark) { Widget _buildCurrentPlan(Map<String, dynamic> sub, bool isDark) {
final planName = sub['plan_name'] ?? sub['plan_name_en'] ?? sub['plan_id'] ?? 'مجانية'; final planName = sub['plan_name'] ?? sub['plan_name_en'] ?? sub['plan_id'] ?? 'مجانية';
final daysLeft = sub['days_remaining'] ?? 0; final daysLeft = sub['days_remaining'] ?? 0;

View File

@@ -892,10 +892,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.18" version: "0.12.19"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
@@ -1465,10 +1465,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.9" version: "0.7.10"
timing: timing:
dependency: transitive dependency: transitive
description: description:

View File

@@ -1,7 +1,7 @@
name: musadaq_app name: musadaq_app
description: Jordanian E-Invoicing Automation SaaS description: Jordanian E-Invoicing Automation SaaS
publish_to: 'none' publish_to: 'none'
version: 1.0.3+3 version: 1.0.5+5
environment: environment:
sdk: '>=3.2.0 <4.0.0' sdk: '>=3.2.0 <4.0.0'