diff --git a/siro_rider/ios/Podfile.lock b/siro_rider/ios/Podfile.lock index 6ba35cd6..0f0ecfa3 100644 --- a/siro_rider/ios/Podfile.lock +++ b/siro_rider/ios/Podfile.lock @@ -129,6 +129,8 @@ PODS: - nanopb/encode (= 3.30910.0) - nanopb/decode (3.30910.0) - nanopb/encode (3.30910.0) + - native_geofence (1.0.0): + - Flutter - package_info_plus (0.4.5): - Flutter - permission_handler_apple (9.4.8): @@ -143,8 +145,6 @@ PODS: - Flutter - share_plus (0.0.1): - Flutter - - sign_in_with_apple (0.0.1): - - Flutter - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS @@ -186,13 +186,13 @@ DEPENDENCIES: - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - location (from `.symlinks/plugins/location/ios`) - maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`) + - native_geofence (from `.symlinks/plugins/native_geofence/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`) - record_ios (from `.symlinks/plugins/record_ios/ios`) - sensors_plus (from `.symlinks/plugins/sensors_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - vibration (from `.symlinks/plugins/vibration/ios`) @@ -266,6 +266,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/location/ios" maplibre_gl: :path: ".symlinks/plugins/maplibre_gl/ios" + native_geofence: + :path: ".symlinks/plugins/native_geofence/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" permission_handler_apple: @@ -278,8 +280,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sensors_plus/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" - sign_in_with_apple: - :path: ".symlinks/plugins/sign_in_with_apple/ios" sqflite_darwin: :path: ".symlinks/plugins/sqflite_darwin/darwin" url_launcher_ios: @@ -330,6 +330,7 @@ SPEC CHECKSUMS: MapLibre: 7f24faba45439f80ccb0f83393c29fa32cb81952 maplibre_gl: a2114567cbd1065866614fbd34dfb75ab782aaa2 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + native_geofence: 653ba9ea1aa7ff9b9a62a883b00d8df14d2945f6 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 permission_handler_apple: 92d754bbaa7361d436db2d6c3c1c2a0fdcec462e PromisesObjC: 752c3227f599e3467650e47ea36f433eeb10c273 @@ -338,7 +339,6 @@ SPEC CHECKSUMS: record_ios: 980fd386a97a35987d0fce3dfda4b26a38c90f4c sensors_plus: 3c3bac724a2128c895623e03efd82cf0e94fd8e8 share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a - sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 TOCropViewController: 797deaf39c90e6e9ddd848d88817f6b9a8a09888 url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b diff --git a/siro_rider/ios/Runner.xcodeproj/project.pbxproj b/siro_rider/ios/Runner.xcodeproj/project.pbxproj index 947d1098..772612bc 100644 --- a/siro_rider/ios/Runner.xcodeproj/project.pbxproj +++ b/siro_rider/ios/Runner.xcodeproj/project.pbxproj @@ -646,7 +646,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -667,7 +667,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Siro; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -782,7 +782,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -833,7 +833,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -856,7 +856,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Siro; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -882,7 +882,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Siro; - IPHONEOS_DEPLOYMENT_TARGET = 15.6; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/siro_rider/ios/Runner/AppDelegate.swift b/siro_rider/ios/Runner/AppDelegate.swift index 7d3e383c..27ac0955 100644 --- a/siro_rider/ios/Runner/AppDelegate.swift +++ b/siro_rider/ios/Runner/AppDelegate.swift @@ -1,6 +1,7 @@ import UIKit import Flutter import FirebaseCore +import native_geofence @main @objc class AppDelegate: FlutterAppDelegate { @@ -10,7 +11,10 @@ import FirebaseCore didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - + // --- 1. تسجيل callback الإضافات للخلفية (مطلوب لـ native_geofence) --- + NativeGeofencePlugin.setPluginRegistrantCallback { registry in + GeneratedPluginRegistrant.register(with: registry) + } // --- 2. تهيئة Firebase --- FirebaseApp.configure() diff --git a/siro_rider/lib/controller/local/ar_eg.dart b/siro_rider/lib/controller/local/ar_eg.dart index 880cc96f..a2db8419 100644 --- a/siro_rider/lib/controller/local/ar_eg.dart +++ b/siro_rider/lib/controller/local/ar_eg.dart @@ -1723,4 +1723,34 @@ final Map ar_eg = { "Enter Code (e.g. AB1234)": "أدخل الكود (مثل: AB1234)", "Link": "ربط", "Please enter a referral code": "من فضلك أدخل كود الإحالة", + + // ========= Siro Prime ========= + "Siro Prime": "سيرو برايم", + "Siro Prime Active": "سيرو برايم نشط", + "No surge pricing. Priority rides. Tap to learn more.": "بدون أسعار ذروة. أولوية في الرحلات. اضغط لمعرفة المزيد.", + "Valid until": "صالح حتى", + "Active until": "نشط حتى", + "What you get with Prime": "ما ستحصل عليه مع برايم", + "No Surge Pricing": "بلا أسعار ذروة", + "Never pay extra during peak hours. Your price stays fixed regardless of demand.": "لن تدفع أكثر في أوقات الذروة. سعرك ثابت بغض النظر عن الطلب.", + "Priority Matching": "أولوية في التطابق", + "Your ride request reaches drivers who have destinations near you first.": "طلب رحلتك يصل أولاً للسائقين المتجهين بالقرب منك.", + "Prime Badge": "شارة برايم", + "Drivers can see your Prime status, making them more likely to accept your request quickly.": "السائقون يرون حالة برايم لديك مما يزيد احتمال قبول طلبك بسرعة.", + "Save Every Ride": "وفّر في كل رحلة", + "During rush hours, surge pricing can add 50–200% to your fare. Prime protects you completely.": "في أوقات الذروة قد ترتفع الأسعار 50-200%. برايم يحميك تماماً.", + "Monthly Subscription": "اشتراك شهري", + "month": "شهر", + "Subscribe Now": "اشترك الآن", + "Already subscribed": "أنت مشترك بالفعل", + "The Premium Ride Experience": "تجربة ركوب مميزة", + "You are a Prime member!": "أنت عضو برايم!", + "You are now a Siro Prime member! Enjoy no surge pricing for 30 days.": "أنت الآن عضو سيرو برايم! استمتع بأسعار بدون ذروة لمدة 30 يوماً.", + "Great!": "رائع!", + "Insufficient Balance": "رصيد غير كافٍ", + "Your current balance": "رصيدك الحالي", + "Required": "المطلوب", + "Please top up your wallet to subscribe to Siro Prime.": "يرجى شحن محفظتك للاشتراك في سيرو برايم.", + "Top Up Wallet": "شحن المحفظة", + "• Subscription renews automatically every 30 days\n• Cancel anytime from your wallet page\n• Amount is deducted from your in-app wallet": "• يتجدد الاشتراك تلقائياً كل 30 يوماً\n• يمكن الإلغاء في أي وقت من صفحة المحفظة\n• يُخصم المبلغ من محفظتك داخل التطبيق", }; diff --git a/siro_rider/lib/controller/local/ar_jo.dart b/siro_rider/lib/controller/local/ar_jo.dart index 44d91832..a3bb209e 100644 --- a/siro_rider/lib/controller/local/ar_jo.dart +++ b/siro_rider/lib/controller/local/ar_jo.dart @@ -1723,4 +1723,34 @@ final Map ar_jo = { "Enter Code (e.g. AB1234)": "أدخل الرمز (مثال: AB1234)", "Link": "ربط", "Please enter a referral code": "يرجى إدخال رمز الإحالة", + + // ========= Siro Prime ========= + "Siro Prime": "سيرو برايم", + "Siro Prime Active": "سيرو برايم نشط", + "No surge pricing. Priority rides. Tap to learn more.": "بدون أسعار ذروة. أولوية في الرحلات. اضغط لمعرفة المزيد.", + "Valid until": "صالح حتى", + "Active until": "نشط حتى", + "What you get with Prime": "ما ستحصل عليه مع برايم", + "No Surge Pricing": "بلا أسعار ذروة", + "Never pay extra during peak hours. Your price stays fixed regardless of demand.": "لن تدفع أكثر في أوقات الذروة. سعرك ثابت بغض النظر عن الطلب.", + "Priority Matching": "أولوية في التطابق", + "Your ride request reaches drivers who have destinations near you first.": "طلب رحلتك يصل أولاً للسائقين المتجهين بالقرب منك.", + "Prime Badge": "شارة برايم", + "Drivers can see your Prime status, making them more likely to accept your request quickly.": "السائقون يرون حالة برايم لديك مما يزيد احتمال قبول طلبك بسرعة.", + "Save Every Ride": "وفّر في كل رحلة", + "During rush hours, surge pricing can add 50–200% to your fare. Prime protects you completely.": "في أوقات الذروة قد ترتفع الأسعار 50-200%. برايم يحميك تماماً.", + "Monthly Subscription": "اشتراك شهري", + "month": "شهر", + "Subscribe Now": "اشترك الآن", + "Already subscribed": "أنت مشترك بالفعل", + "The Premium Ride Experience": "تجربة ركوب مميزة", + "You are a Prime member!": "أنت عضو برايم!", + "You are now a Siro Prime member! Enjoy no surge pricing for 30 days.": "أنت الآن عضو سيرو برايم! استمتع بأسعار بدون ذروة لمدة 30 يوماً.", + "Great!": "رائع!", + "Insufficient Balance": "رصيد غير كافٍ", + "Your current balance": "رصيدك الحالي", + "Required": "المطلوب", + "Please top up your wallet to subscribe to Siro Prime.": "يرجى شحن محفظتك للاشتراك في سيرو برايم.", + "Top Up Wallet": "شحن المحفظة", + "• Subscription renews automatically every 30 days\n• Cancel anytime from your wallet page\n• Amount is deducted from your in-app wallet": "• يتجدد الاشتراك تلقائياً كل 30 يوماً\n• يمكن الإلغاء في أي وقت من صفحة المحفظة\n• يُخصم المبلغ من محفظتك داخل التطبيق", }; diff --git a/siro_rider/lib/controller/local/ar_sy.dart b/siro_rider/lib/controller/local/ar_sy.dart index a149ad99..b91a718a 100644 --- a/siro_rider/lib/controller/local/ar_sy.dart +++ b/siro_rider/lib/controller/local/ar_sy.dart @@ -1723,4 +1723,34 @@ final Map ar_sy = { "Enter Code (e.g. AB1234)": "دخل الرمز (مثال: AB1234)", "Link": "ربط", "Please enter a referral code": "دخل رمز الإحالة", + + // ========= Siro Prime ========= + "Siro Prime": "سيرو برايم", + "Siro Prime Active": "سيرو برايم نشط", + "No surge pricing. Priority rides. Tap to learn more.": "بدون أسعار ذروة. أولوية في الرحلات. اضغط لمعرفة المزيد.", + "Valid until": "صالح حتى", + "Active until": "نشط حتى", + "What you get with Prime": "ما ستحصل عليه مع برايم", + "No Surge Pricing": "بلا أسعار ذروة", + "Never pay extra during peak hours. Your price stays fixed regardless of demand.": "لن تدفع أكثر في أوقات الذروة. سعرك ثابت بغض النظر عن الطلب.", + "Priority Matching": "أولوية في التطابق", + "Your ride request reaches drivers who have destinations near you first.": "طلب رحلتك يصل أولاً للسائقين المتجهين بالقرب منك.", + "Prime Badge": "شارة برايم", + "Drivers can see your Prime status, making them more likely to accept your request quickly.": "السائقون يرون حالة برايم لديك مما يزيد احتمال قبول طلبك بسرعة.", + "Save Every Ride": "وفّر في كل رحلة", + "During rush hours, surge pricing can add 50–200% to your fare. Prime protects you completely.": "في أوقات الذروة قد ترتفع الأسعار 50-200%. برايم يحميك تماماً.", + "Monthly Subscription": "اشتراك شهري", + "month": "شهر", + "Subscribe Now": "اشترك الآن", + "Already subscribed": "أنت مشترك بالفعل", + "The Premium Ride Experience": "تجربة ركوب مميزة", + "You are a Prime member!": "أنت عضو برايم!", + "You are now a Siro Prime member! Enjoy no surge pricing for 30 days.": "أنت الآن عضو سيرو برايم! استمتع بأسعار بدون ذروة لمدة 30 يوماً.", + "Great!": "رائع!", + "Insufficient Balance": "رصيد غير كافٍ", + "Your current balance": "رصيدك الحالي", + "Required": "المطلوب", + "Please top up your wallet to subscribe to Siro Prime.": "يرجى شحن محفظتك للاشتراك في سيرو برايم.", + "Top Up Wallet": "شحن المحفظة", + "• Subscription renews automatically every 30 days\n• Cancel anytime from your wallet page\n• Amount is deducted from your in-app wallet": "• يتجدد الاشتراك تلقائياً كل 30 يوماً\n• يمكن الإلغاء في أي وقت من صفحة المحفظة\n• يُخصم المبلغ من محفظتك داخل التطبيق", }; diff --git a/siro_rider/lib/views/home/my_wallet/siro_prime_page.dart b/siro_rider/lib/views/home/my_wallet/siro_prime_page.dart index 9037fa99..58d5c5d0 100644 --- a/siro_rider/lib/views/home/my_wallet/siro_prime_page.dart +++ b/siro_rider/lib/views/home/my_wallet/siro_prime_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:siro_rider/constant/box_name.dart'; +import 'package:siro_rider/constant/colors.dart'; +import 'package:siro_rider/constant/style.dart'; import 'package:siro_rider/controller/payment/prime_controller.dart'; import 'package:siro_rider/main.dart'; import 'dart:math' as math; @@ -20,6 +22,10 @@ class _SiroPrimePageState extends State final PrimeController ctrl = Get.find(); + // ── Brand gradient (ثابتة — Prime هوية مستقلة ضمن التطبيق) ────── + static const _primeGradient = [Color(0xFF7C3AED), Color(0xFFDB2777)]; + static const _primeGradientStart = Color(0xFF7C3AED); + @override void initState() { super.initState(); @@ -47,97 +53,113 @@ class _SiroPrimePageState extends State @override Widget build(BuildContext context) { + // ── الخلفية تتكيف مع وضع التطبيق ──────────────────────────── + final bool isDark = Get.isDarkMode; + final bgColor = isDark ? const Color(0xFF0D0D1A) : const Color(0xFFF0EFFA); + final surfaceColor = isDark ? const Color(0xFF1A1A2E) : Colors.white; + return Scaffold( - backgroundColor: const Color(0xFF0D0D1A), + backgroundColor: bgColor, body: CustomScrollView( slivers: [ - // ─── Animated Header ──────────────────────────────────── + // ─── SliverAppBar ──────────────────────────────────────── SliverAppBar( - expandedHeight: 280, - backgroundColor: Colors.transparent, + expandedHeight: 270, + backgroundColor: + isDark ? const Color(0xFF0D0D1A) : const Color(0xFFF0EFFA), elevation: 0, pinned: true, leading: IconButton( - icon: const Icon(Icons.arrow_back_ios_new, color: Colors.white), + icon: Icon(Icons.arrow_back_ios_new, + color: isDark ? Colors.white : AppColor.primaryColor), onPressed: () => Get.back(), ), flexibleSpace: FlexibleSpaceBar( - background: _buildHeader(), + background: _buildHeader(isDark), ), ), - // ─── Content ───────────────────────────────────────────── + // ─── Body ──────────────────────────────────────────────── SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // Status Card - _buildStatusCard(), - const SizedBox(height: 28), + const SizedBox(height: 4), + _buildStatusCard(surfaceColor, isDark), + const SizedBox(height: 24), - // Benefits Title + // Benefits title Text( 'What you get with Prime'.tr, - style: const TextStyle( - color: Colors.white, - fontSize: 20, + style: AppStyle.title.copyWith( + color: AppColor.writeColor, + fontSize: 18, fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 16), + const SizedBox(height: 14), - // Benefits List _buildBenefit( icon: '🚫', title: 'No Surge Pricing'.tr, - subtitle: 'Never pay extra during peak hours. Your price stays fixed regardless of demand.'.tr, - gradient: [const Color(0xFF7C3AED), const Color(0xFF4F46E5)], + subtitle: + 'Never pay extra during peak hours. Your price stays fixed regardless of demand.' + .tr, + gradient: const [Color(0xFF7C3AED), Color(0xFF4F46E5)], + surfaceColor: surfaceColor, + isDark: isDark, ), _buildBenefit( icon: '⚡', title: 'Priority Matching'.tr, - subtitle: 'Your ride request reaches drivers who have destinations near you first.'.tr, - gradient: [const Color(0xFFDB2777), const Color(0xFF9333EA)], + subtitle: + 'Your ride request reaches drivers who have destinations near you first.' + .tr, + gradient: const [Color(0xFFDB2777), Color(0xFF9333EA)], + surfaceColor: surfaceColor, + isDark: isDark, ), _buildBenefit( icon: '👑', title: 'Prime Badge'.tr, - subtitle: 'Drivers can see your Prime status, making them more likely to accept your request quickly.'.tr, - gradient: [const Color(0xFFD97706), const Color(0xFFEF4444)], + subtitle: + 'Drivers can see your Prime status, making them more likely to accept your request quickly.' + .tr, + gradient: const [Color(0xFFD97706), Color(0xFFEF4444)], + surfaceColor: surfaceColor, + isDark: isDark, ), _buildBenefit( icon: '💰', title: 'Save Every Ride'.tr, - subtitle: 'During rush hours, surge pricing can add 50–200% to your fare. Prime protects you completely.'.tr, - gradient: [const Color(0xFF059669), const Color(0xFF0891B2)], + subtitle: + 'During rush hours, surge pricing can add 50–200% to your fare. Prime protects you completely.' + .tr, + gradient: const [Color(0xFF059669), Color(0xFF0891B2)], + surfaceColor: surfaceColor, + isDark: isDark, ), - const SizedBox(height: 32), - - // Price Card - _buildPriceCard(), - + const SizedBox(height: 28), + _buildPriceCard(surfaceColor, isDark), const SizedBox(height: 16), - - // Subscribe Button _buildSubscribeButton(), + const SizedBox(height: 20), - const SizedBox(height: 24), - - // Fine Print + // Fine print Text( - '• Subscription renews automatically every 30 days\n• Cancel anytime from your wallet page\n• Amount is deducted from your in-app wallet'.tr, + '• Subscription renews automatically every 30 days\n• Cancel anytime from your wallet page\n• Amount is deducted from your in-app wallet' + .tr, style: TextStyle( - color: Colors.white.withOpacity(0.4), - fontSize: 12, + color: AppColor.grayColor, + fontSize: 11, height: 1.8, ), textAlign: TextAlign.center, ), - - const SizedBox(height: 40), + const SizedBox(height: 36), ], ), ), @@ -147,15 +169,17 @@ class _SiroPrimePageState extends State ); } - // ─── Header ────────────────────────────────────────────────── - Widget _buildHeader() { + // ─── Header ─────────────────────────────────────────────────────── + Widget _buildHeader(bool isDark) { return AnimatedBuilder( animation: _shimmerController, builder: (context, child) { return Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( gradient: LinearGradient( - colors: [Color(0xFF1A0A2E), Color(0xFF0D0D1A)], + colors: isDark + ? [const Color(0xFF1A0A2E), const Color(0xFF0D0D1A)] + : [const Color(0xFFEDE9FE), const Color(0xFFF0EFFA)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), @@ -163,10 +187,7 @@ class _SiroPrimePageState extends State child: Stack( alignment: Alignment.center, children: [ - // Background particles - ..._buildParticles(), - - // Crown + Title + ..._buildParticles(isDark), Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -174,47 +195,53 @@ class _SiroPrimePageState extends State ScaleTransition( scale: _pulseAnimation, child: Container( - width: 90, - height: 90, + width: 88, + height: 88, decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( - colors: [Color(0xFF7C3AED), Color(0xFFDB2777)], + colors: _primeGradient, ), boxShadow: [ BoxShadow( - color: const Color(0xFF7C3AED).withOpacity(0.6), - blurRadius: 30, - spreadRadius: 5, + color: _primeGradientStart.withOpacity(0.5), + blurRadius: 28, + spreadRadius: 4, ), ], ), child: const Center( - child: Text('👑', style: TextStyle(fontSize: 44)), + child: Text('👑', style: TextStyle(fontSize: 42)), ), ), ), - const SizedBox(height: 16), + const SizedBox(height: 14), ShaderMask( shaderCallback: (bounds) => const LinearGradient( - colors: [Color(0xFFE879F9), Color(0xFF818CF8), Color(0xFFF59E0B)], + colors: [ + Color(0xFFE879F9), + Color(0xFF818CF8), + Color(0xFFF59E0B) + ], ).createShader(bounds), child: const Text( 'SIRO PRIME', style: TextStyle( - fontSize: 32, + fontSize: 30, fontWeight: FontWeight.w900, color: Colors.white, letterSpacing: 4, ), ), ), - const SizedBox(height: 8), + const SizedBox(height: 6), Text( 'The Premium Ride Experience'.tr, style: TextStyle( - color: Colors.white.withOpacity(0.6), - fontSize: 14, + color: isDark + ? Colors.white.withOpacity(0.55) + : AppColor.primaryColor.withOpacity(0.6), + fontSize: 13, ), ), ], @@ -226,23 +253,23 @@ class _SiroPrimePageState extends State ); } - List _buildParticles() { + List _buildParticles(bool isDark) { return List.generate(8, (i) { final angle = (i / 8) * 2 * math.pi; - final radius = 120.0 + (i % 3) * 30; + final radius = 110.0 + (i % 3) * 28; final size = 3.0 + (i % 4).toDouble(); final opacity = - (0.1 + (_shimmerController.value + i / 8) % 1.0 * 0.5).clamp(0.0, 0.6); + (0.08 + (_shimmerController.value + i / 8) % 1.0 * 0.4).clamp(0.0, 0.5); return Positioned( left: MediaQuery.of(context).size.width / 2 + math.cos(angle) * radius - 5, - top: 140 + math.sin(angle) * 80, + top: 130 + math.sin(angle) * 75, child: Opacity( opacity: opacity, child: Container( width: size, height: size, - decoration: const BoxDecoration( - color: Color(0xFFE879F9), + decoration: BoxDecoration( + color: isDark ? const Color(0xFFE879F9) : _primeGradientStart, shape: BoxShape.circle, ), ), @@ -251,8 +278,8 @@ class _SiroPrimePageState extends State }); } - // ─── Status Card ────────────────────────────────────────────── - Widget _buildStatusCard() { + // ─── Status Card ────────────────────────────────────────────────── + Widget _buildStatusCard(Color surfaceColor, bool isDark) { return GetBuilder( builder: (c) { if (!c.isPrime) return const SizedBox.shrink(); @@ -260,27 +287,37 @@ class _SiroPrimePageState extends State padding: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - gradient: const LinearGradient( - colors: [Color(0xFF7C3AED), Color(0xFFDB2777)], - ), + gradient: const LinearGradient(colors: _primeGradient), + boxShadow: [ + BoxShadow( + color: _primeGradientStart.withOpacity(0.3), + blurRadius: 16, + offset: const Offset(0, 6), + ) + ], ), child: Row( children: [ - const Icon(Icons.verified, color: Colors.white, size: 28), + const Icon(Icons.verified, color: Colors.white, size: 26), const SizedBox(width: 12), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('You are a Prime member!'.tr, - style: const TextStyle( - color: Colors.white, fontWeight: FontWeight.bold)), - if (c.expireAt != null) - Text( - '${'Active until'.tr}: ${c.expireAt!.substring(0, 10)}', - style: TextStyle( - color: Colors.white.withOpacity(0.8), fontSize: 12), - ), - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('You are a Prime member!'.tr, + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 14)), + if (c.expireAt != null) + Text( + '${'Active until'.tr}: ${c.expireAt!.substring(0, 10)}', + style: TextStyle( + color: Colors.white.withOpacity(0.8), + fontSize: 12), + ), + ], + ), ), ], ), @@ -289,33 +326,42 @@ class _SiroPrimePageState extends State ); } - // ─── Benefit Card ──────────────────────────────────────────── + // ─── Benefit Card ───────────────────────────────────────────────── Widget _buildBenefit({ required String icon, required String title, required String subtitle, required List gradient, + required Color surfaceColor, + required bool isDark, }) { return Container( - margin: const EdgeInsets.only(bottom: 12), + margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Colors.white.withOpacity(0.05), - border: Border.all(color: Colors.white.withOpacity(0.08)), + color: surfaceColor, + border: Border.all(color: AppColor.borderColor), + boxShadow: [ + if (!isDark) + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 8, + offset: const Offset(0, 3)) + ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: 48, - height: 48, + width: 46, + height: 46, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), gradient: LinearGradient(colors: gradient), ), child: Center( - child: Text(icon, style: const TextStyle(fontSize: 22)), + child: Text(icon, style: const TextStyle(fontSize: 21)), ), ), const SizedBox(width: 14), @@ -324,14 +370,16 @@ class _SiroPrimePageState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.w600, - fontSize: 15)), + style: AppStyle.title.copyWith( + color: AppColor.writeColor, + fontSize: 14, + fontWeight: FontWeight.w700)), const SizedBox(height: 4), Text(subtitle, style: TextStyle( - color: Colors.white.withOpacity(0.55), fontSize: 13, height: 1.5)), + color: AppColor.grayColor, + fontSize: 12, + height: 1.5)), ], ), ), @@ -340,10 +388,10 @@ class _SiroPrimePageState extends State ); } - // ─── Price Card ─────────────────────────────────────────────── - Widget _buildPriceCard() { + // ─── Price Card ─────────────────────────────────────────────────── + Widget _buildPriceCard(Color surfaceColor, bool isDark) { final country = box.read(BoxName.countryCode) ?? 'Jordan'; - final pricing = { + const pricing = { 'Jordan': {'price': '3', 'currency': 'JOD'}, 'Egypt': {'price': '200', 'currency': 'EGP'}, 'Syria': {'price': '500', 'currency': 'SYP'}, @@ -354,13 +402,22 @@ class _SiroPrimePageState extends State padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), - border: Border.all(color: const Color(0xFF7C3AED).withOpacity(0.4), width: 1.5), - color: const Color(0xFF7C3AED).withOpacity(0.08), + color: surfaceColor, + border: Border.all( + color: _primeGradientStart.withOpacity(isDark ? 0.4 : 0.25), + width: 1.5), + boxShadow: [ + if (!isDark) + BoxShadow( + color: _primeGradientStart.withOpacity(0.08), + blurRadius: 16, + offset: const Offset(0, 6)) + ], ), child: Column( children: [ Text('Monthly Subscription'.tr, - style: TextStyle(color: Colors.white.withOpacity(0.6), fontSize: 13)), + style: TextStyle(color: AppColor.grayColor, fontSize: 12)), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -368,11 +425,10 @@ class _SiroPrimePageState extends State children: [ Text( p['price']!, - style: const TextStyle( - color: Colors.white, - fontSize: 48, - fontWeight: FontWeight.w900, - ), + style: TextStyle( + color: AppColor.writeColor, + fontSize: 46, + fontWeight: FontWeight.w900), ), const SizedBox(width: 6), Padding( @@ -380,59 +436,63 @@ class _SiroPrimePageState extends State child: Text( p['currency']!, style: const TextStyle( - color: Color(0xFFE879F9), - fontSize: 18, - fontWeight: FontWeight.bold, - ), + color: Color(0xFF7C3AED), + fontSize: 17, + fontWeight: FontWeight.bold), ), ), ], ), - Text( - '≈ \$4 USD / ${'month'.tr}', - style: TextStyle(color: Colors.white.withOpacity(0.4), fontSize: 12), - ), + Text('≈ \$4 USD / ${'month'.tr}', + style: TextStyle(color: AppColor.grayColor, fontSize: 11)), ], ), ); } - // ─── Subscribe Button ───────────────────────────────────────── + // ─── Subscribe Button ───────────────────────────────────────────── Widget _buildSubscribeButton() { return GetBuilder( builder: (c) { + // Already subscribed state if (c.isPrime) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Colors.green.withOpacity(0.15), - border: Border.all(color: Colors.green.withOpacity(0.4)), + color: AppColor.greenColor.withOpacity(0.1), + border: Border.all(color: AppColor.greenColor.withOpacity(0.4)), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(Icons.check_circle, color: Colors.green), + const Icon(Icons.check_circle, color: AppColor.greenColor), const SizedBox(width: 8), Text('Already subscribed'.tr, style: const TextStyle( - color: Colors.green, fontWeight: FontWeight.bold)), + color: AppColor.greenColor, + fontWeight: FontWeight.bold)), ], ), ); } + // Subscribe button with animated gradient return GestureDetector( onTap: c.isLoading ? null : () => c.subscribePrime(context), child: AnimatedBuilder( animation: _shimmerController, builder: (context, child) { return Container( - height: 56, + height: 54, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( - colors: const [Color(0xFF7C3AED), Color(0xFFDB2777), Color(0xFFD97706)], + colors: const [ + Color(0xFF7C3AED), + Color(0xFFDB2777), + Color(0xFFD97706), + ], stops: [ 0, (_shimmerController.value + 0.5) % 1.0, @@ -441,8 +501,8 @@ class _SiroPrimePageState extends State ), boxShadow: [ BoxShadow( - color: const Color(0xFF7C3AED).withOpacity(0.5), - blurRadius: 20, + color: _primeGradientStart.withOpacity(0.4), + blurRadius: 18, offset: const Offset(0, 8), ), ], @@ -450,24 +510,23 @@ class _SiroPrimePageState extends State child: Center( child: c.isLoading ? const SizedBox( - width: 24, - height: 24, + width: 22, + height: 22, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text('👑', style: TextStyle(fontSize: 20)), + const Text('👑', style: TextStyle(fontSize: 19)), const SizedBox(width: 8), Text( 'Subscribe Now'.tr, style: const TextStyle( - color: Colors.white, - fontSize: 17, - fontWeight: FontWeight.bold, - letterSpacing: 0.5, - ), + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + letterSpacing: 0.5), ), ], ),