import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/controller/profile/captain_profile_controller.dart'; import 'package:sefer_driver/main.dart'; import 'package:sefer_driver/views/auth/captin/criminal_documents_page.dart'; import 'package:sefer_driver/views/widgets/my_scafold.dart'; import 'package:sefer_driver/views/widgets/mycircular.dart'; import 'package:sefer_driver/views/widgets/mydialoug.dart'; import '../../../constant/links.dart'; import '../../../controller/functions/crud.dart'; import 'behavior_page.dart'; import 'captains_cars.dart'; // الصفحة الرئيسية الجديدة class ProfileCaptain extends StatelessWidget { const ProfileCaptain({super.key}); @override Widget build(BuildContext context) { // Get.put() يجب أن يكون في مكان يتم استدعاؤه مرة واحدة فقط، // لكن سنبقيه هنا حسب الكود الأصلي final controller = Get.put(CaptainProfileController()); return MyScafolld( title: 'My Profile'.tr, isleading: true, body: [ GetBuilder( builder: (controller) { if (controller.isLoading) { return const Center(child: MyCircularProgressIndicator()); } if (controller.captainProfileData.isEmpty) { return Center(child: Text('Failed to load profile data.'.tr)); } return SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0), child: Column( children: [ // 1. رأس الصفحة: صورة واسم وتقييم ProfileHeader( name: '${controller.captainProfileData['first_name'] ?? ''} ${controller.captainProfileData['last_name'] ?? ''}', rating: controller.captainProfileData['ratingDriver'] != null ? double.tryParse(controller .captainProfileData['ratingDriver'] .toString()) ?? 0.0 : 0.0, ratingCount: int.tryParse(controller .captainProfileData['ratingCount'] .toString()) ?? 0, ), const SizedBox(height: 24), // 2. قسم الإجراءات السريعة ActionsGrid(), const SizedBox(height: 24), // 3. بطاقة المعلومات الشخصية PersonalInfoCard( data: controller.captainProfileData .cast()), const SizedBox(height: 16), // 4. بطاقة معلومات المركبة (قابلة للتوسيع) VehicleInfoCard( data: controller.captainProfileData .cast()), ], ), ); }, ), ], ); } } // --- الويدجتس الجديدة المنفصلة لتحسين التصميم --- /// 1. ويدجت رأس الصفحة class ProfileHeader extends StatelessWidget { final String name; final double rating; final int ratingCount; const ProfileHeader({ super.key, required this.name, required this.rating, required this.ratingCount, }); @override Widget build(BuildContext context) { return Column( children: [ CircleAvatar( radius: 50, backgroundColor: Get.theme.primaryColor.withOpacity(0.1), child: Icon(Icons.person, size: 60, color: Get.theme.primaryColor), ), const SizedBox(height: 12), Text( name, style: Get.textTheme.headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.star, color: Colors.amber, size: 20), const SizedBox(width: 4), Text( '${rating.toStringAsFixed(1)} (${'reviews'.tr} $ratingCount)', style: Get.textTheme.titleMedium ?.copyWith(color: Colors.grey.shade600), ), ], ), ], ); } } /// 2. ويدجت شبكة الأزرار class ActionsGrid extends StatelessWidget { const ActionsGrid({super.key}); @override Widget build(BuildContext context) { return GridView.count( crossAxisCount: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 2.5, // للتحكم في ارتفاع الأزرار children: [ // _ActionTile( // title: 'My Cars'.tr, // icon: Icons.directions_car_filled, // onTap: () => Get.to(() => CaptainsCars()), // ), // _ActionTile( // title: 'Criminal Record'.tr, // icon: Icons.description, // onTap: () => Get.to(() => CriminalDocumemtPage()), // ), _ActionTile( title: 'ShamCash Account'.tr, // غيرت الاسم ليكون أوضح icon: Icons.account_balance_wallet_rounded, // أيقونة محفظة // trailing: Icon(Icons.arrow_forward_ios, // size: 16, color: Colors.grey), // سهم صغير للجمالية onTap: () { // استدعاء دالة فتح النافذة showShamCashInput(); }, ), _ActionTile( title: 'Behavior Page'.tr, icon: Icons.checklist_rtl, onTap: () => Get.to(() => BehaviorPage()), ), ], ); } } void showShamCashInput() { // 1. القراءة من الذاكرة المحلية (GetStorage) عند فتح النافذة // إذا لم يتم العثور على قيمة، يتم تعيينها إلى نص فارغ final String existingName = box.read('shamcash_name') ?? ''; final String existingCode = box.read('shamcash_code') ?? ''; // تعريف أدوات التحكم للحقلين مع تحميل القيمة المحفوظة final TextEditingController nameController = TextEditingController(text: existingName); final TextEditingController codeController = TextEditingController(text: existingCode); Get.bottomSheet( Container( padding: const EdgeInsets.all(25), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(30)), boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 10, offset: Offset(0, -2)) ], ), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // --- 1. المقبض العلوي --- Center( child: Container( height: 5, width: 50, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(10)), margin: const EdgeInsets.only(bottom: 20), ), ), // --- 2. العنوان والأيقونة --- Image.asset( 'assets/images/shamCash.png', height: 50, ), // const Icon(Icons.account_balance_wallet_rounded, // size: 45, color: Colors.blueAccent), const SizedBox(height: 10), Text( "ربط حساب شام كاش 🔗", textAlign: TextAlign.center, style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.blueGrey[900]), ), const SizedBox(height: 5), const Text( "أدخل بيانات حسابك لاستقبال الأرباح فوراً", textAlign: TextAlign.center, style: TextStyle(fontSize: 13, color: Colors.grey), ), const SizedBox(height: 25), // --- 3. الحقل الأول: اسم الحساب (أعلى الباركود) --- const Text("1. اسم الحساب (أعلى الباركود)", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), const SizedBox(height: 8), Container( decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!), ), child: TextField( controller: nameController, decoration: InputDecoration( hintText: "مثال: intaleq", hintStyle: TextStyle(color: Colors.grey[400], fontSize: 13), border: InputBorder.none, prefixIcon: const Icon(Icons.person_outline_rounded, color: Colors.blueGrey), contentPadding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10), ), ), ), const SizedBox(height: 15), // --- 4. الحقل الثاني: الكود (أسفل الباركود) --- const Text("2. كود المحفظة (أسفل الباركود)", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), const SizedBox(height: 8), Container( decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!), ), child: TextField( controller: codeController, style: const TextStyle( fontSize: 13, letterSpacing: 0.5), // خط أصغر قليلاً للكود الطويل decoration: InputDecoration( hintText: "مثال: 80f23afe40...", hintStyle: TextStyle(color: Colors.grey[400], fontSize: 13), border: InputBorder.none, prefixIcon: const Icon(Icons.qr_code_2_rounded, color: Colors.blueGrey), contentPadding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10), // زر لصق الكود suffixIcon: IconButton( icon: const Icon(Icons.paste_rounded, color: Colors.blue), tooltip: "لصق الكود", onPressed: () async { ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); if (data != null && data.text != null) { codeController.text = data.text!; // تحريك المؤشر للنهاية بعد اللصق codeController.selection = TextSelection.fromPosition( TextPosition(offset: codeController.text.length), ); } }, ), ), ), ), const SizedBox(height: 30), // --- 5. زر الحفظ --- SizedBox( height: 50, child: ElevatedButton( onPressed: () async { String name = nameController.text.trim(); String code = codeController.text.trim(); // التحقق من صحة البيانات if (name.isNotEmpty && code.length > 5) { // 1. إرسال البيانات إلى السيرفر var res = await CRUD() .post(link: AppLink.updateShamCashDriver, payload: { "id": box.read(BoxName.driverID), "accountBank": name, "bankCode": code, }); if (res != 'failure') { // 2. 🔴 الحفظ في الذاكرة المحلية (GetStorage) بعد نجاح التحديث box.write('shamcash_name', name); box.write('shamcash_code', code); Get.back(); // إغلاق النافذة Get.snackbar( "تم الحفظ بنجاح", "تم ربط حساب ($name) لاستلام الأرباح.", backgroundColor: Colors.green, colorText: Colors.white, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(20), icon: const Icon(Icons.check_circle_outline, color: Colors.white), ); return; } else { // في حال فشل الإرسال إلى السيرفر Get.snackbar( "خطأ في السيرفر", "فشل تحديث البيانات، يرجى المحاولة لاحقاً.", backgroundColor: Colors.redAccent, colorText: Colors.white, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(20), ); } } else { Get.snackbar( "بيانات ناقصة", "يرجى التأكد من إدخال الاسم والكود بشكل صحيح.", backgroundColor: Colors.orange, colorText: Colors.white, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(20), ); } }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF2ecc71), // الأخضر المالي shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12)), elevation: 2, ), child: const Text( "حفظ وتفعيل الحساب", style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white), ), ), ), const SizedBox(height: 10), // مسافة سفلية إضافية للأمان ], ), ), ), isScrollControlled: true, // ضروري لرفع النافذة عند فتح الكيبورد ); } /// ويدجت داخلية لزر في الشبكة class _ActionTile extends StatelessWidget { final String title; final IconData icon; final VoidCallback onTap; const _ActionTile( {required this.title, required this.icon, required this.onTap}); @override Widget build(BuildContext context) { return Material( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(12), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: Get.theme.primaryColor, size: 20), const SizedBox(width: 8), Flexible( child: Text( title, style: Get.textTheme.labelLarge, textAlign: TextAlign.center, )), ], ), ), ), ); } } /// 3. بطاقة المعلومات الشخصية class PersonalInfoCard extends StatelessWidget { final Map data; PersonalInfoCard({super.key, required this.data}); final controller = Get.find(); @override Widget build(BuildContext context) { return Card( elevation: 2, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Personal Information'.tr, style: Get.textTheme.titleLarge), const Divider(height: 24), _InfoRow( icon: Icons.phone, label: 'Phone Number'.tr, value: data['phone'] ?? ''), if (data['email'] != null && data['email'].toString().contains('intaleqapp')) ...[ TextFormField( controller: controller.emailController, keyboardType: TextInputType.emailAddress, // ✅ لوحة مفاتيح خاصة بالإيميل decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Email'.tr, hintText: 'Enter your email'.tr, prefixIcon: Icon(Icons.email), ), autofillHints: [ AutofillHints.email ], // اختياري لتحسين تجربة المستخدم ), const SizedBox(height: 10), ElevatedButton( onPressed: () async { await controller.updateEmail(); }, child: Text('Update'.tr), ), ] else _InfoRow( icon: Icons.email, label: 'Email'.tr, value: data['email'] ?? '', ), _InfoRow( icon: Icons.cake, label: 'Age'.tr, value: data['age']?.toString() ?? 'N/A'), _InfoRow( icon: Icons.wc, label: 'Gender'.tr, value: data['gender'] ?? 'N/A'), ], ), ), ); } } /// 4. بطاقة معلومات المركبة class VehicleInfoCard extends StatelessWidget { final Map data; const VehicleInfoCard({super.key, required this.data}); @override Widget build(BuildContext context) { return Card( elevation: 2, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: ExpansionTile( title: Text('Vehicle Details'.tr, style: Get.textTheme.titleLarge), leading: Icon(Icons.directions_car, color: Get.theme.primaryColor), childrenPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), children: [ _InfoRow( icon: Icons.branding_watermark, label: 'Make'.tr, value: data['make'] ?? ''), _InfoRow( icon: Icons.category, label: 'Model'.tr, value: data['model'] ?? ''), _InfoRow( icon: Icons.palette, label: 'Color'.tr, value: data['color'] ?? ''), _InfoRow( icon: Icons.pin, label: 'Plate Number'.tr, value: data['car_plate'] ?? ''), _InfoRow( icon: Icons.confirmation_number, label: 'VIN'.tr, value: data['vin'] ?? ''), _InfoRow( icon: Icons.event, label: 'Expiration Date'.tr, value: data['expiration_date'] ?? ''), ], ), ); } } /// ويدجت لعرض سطر معلومة (أيقونة + عنوان + قيمة) لتجنب التكرار class _InfoRow extends StatelessWidget { final IconData icon; final String label; final String value; const _InfoRow( {required this.icon, required this.label, required this.value}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( children: [ Icon(icon, color: Colors.grey.shade500, size: 20), const SizedBox(width: 16), Text(label, style: Get.textTheme.bodyLarge), const Spacer(), Flexible( child: Text( value, style: Get.textTheme.bodyLarge?.copyWith( color: Colors.grey.shade700, fontWeight: FontWeight.w500), textAlign: TextAlign.end, ), ), ], ), ); } }