Files
intaleq_driver/lib/views/home/Captin/home_captain/drawer_captain.dart
Hamza-Ayed 3c0ae4cf2f 26-1-20/1
2026-01-20 10:11:10 +03:00

376 lines
14 KiB
Dart
Executable File

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/constant/links.dart';
import 'package:sefer_driver/controller/functions/upload_image.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
import 'package:sefer_driver/device_compatibility_page.dart';
import 'package:sefer_driver/main.dart';
// استيراد الصفحات الأخرى... تأكد من صحة المسارات
import 'package:sefer_driver/views/Rate/rate_app_page.dart';
import 'package:sefer_driver/views/auth/captin/contact_us_page.dart';
import 'package:sefer_driver/views/auth/captin/invite_driver_screen.dart';
import 'package:sefer_driver/views/notification/available_rides_page.dart';
import 'package:sefer_driver/views/auth/captin/logout_captain.dart';
import 'package:sefer_driver/views/home/Captin/history/history_captain.dart';
import 'package:sefer_driver/views/home/Captin/home_captain/help_captain.dart';
import 'package:sefer_driver/views/home/Captin/About Us/settings_captain.dart';
import 'package:sefer_driver/views/home/my_wallet/walet_captain.dart';
import 'package:sefer_driver/views/home/profile/profile_captain.dart';
import 'package:sefer_driver/views/notification/notification_captain.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../constant/colors.dart';
import '../About Us/video_page.dart';
import '../assurance_health_page.dart';
import '../maintain_center_page.dart';
// 1. إنشاء Class لتعريف بيانات كل عنصر في القائمة
class DrawerItem {
final String title;
final IconData icon;
final Color color;
final VoidCallback onTap;
DrawerItem(
{required this.title,
required this.icon,
required this.color,
required this.onTap});
}
// --- الويدجت الرئيسية للقائمة الجانبية ---
class AppDrawer extends StatelessWidget {
AppDrawer({super.key});
final ImageController imageController = Get.put(ImageController());
// 2. تعريف بيانات القائمة بشكل مركزي ومنظم
final List<DrawerItem> drawerItems = [
DrawerItem(
title: 'Balance'.tr,
icon: Icons.account_balance_wallet,
color: Colors.green,
onTap: () => Get.to(() => WalletCaptainRefactored())),
DrawerItem(
title: 'Profile'.tr,
icon: Icons.person,
color: Colors.blue,
onTap: () => Get.to(() => ProfileCaptain())),
DrawerItem(
title: 'History of Trip'.tr,
icon: Icons.history,
color: Colors.orange,
onTap: () => Get.to(() => const HistoryCaptain())),
DrawerItem(
title: 'Available for rides'.tr,
icon: Icons.drive_eta,
color: Colors.teal,
onTap: () => Get.to(() => const AvailableRidesPage())),
DrawerItem(
title: 'Notifications'.tr,
icon: Icons.notifications,
color: Colors.purple,
onTap: () => Get.to(() => const NotificationCaptain())),
DrawerItem(
title: 'Helping Center'.tr,
icon: Icons.help_center,
color: Colors.cyan,
onTap: () => Get.to(() => HelpCaptain())),
DrawerItem(
title: 'Share App'.tr,
icon: Icons.share,
color: Colors.indigo,
onTap: () => Get.to(() => InviteScreen())),
// DrawerItem(
// title: 'Maintenance Center'.tr,
// icon: Icons.build,
// color: Colors.brown,
// onTap: () => Get.to(() => MaintainCenterPage())),
// DrawerItem(
// title: 'Health Insurance'.tr,
// icon: Icons.favorite,
// color: Colors.pink,
// onTap: () => Get.to(() => AssuranceHealthPage())),
DrawerItem(
title: 'Contact Us'.tr,
icon: Icons.email,
color: Colors.blueGrey,
onTap: () => Get.to(() => ContactUsPage())),
DrawerItem(
title: 'Videos Tutorials'.tr,
icon: Icons.video_library,
color: Colors.redAccent,
onTap: () => Get.to(() => VideoListPage())),
DrawerItem(
title: 'Rate Our App'.tr,
icon: Icons.star,
color: Colors.amber,
onTap: () => Get.to(() => RatingScreen())),
DrawerItem(
title: 'Is device compatible'.tr,
icon: Icons.memory,
color: Colors.greenAccent,
onTap: () => Get.to(() => DeviceCompatibilityPage())),
DrawerItem(
title: 'Privacy Policy'.tr,
icon: Icons.memory,
color: Colors.greenAccent,
onTap: () =>
launchUrl(Uri.parse('${AppLink.server}/privacy_policy.php'))),
DrawerItem(
title: 'Settings'.tr,
icon: Icons.settings,
color: Colors.grey.shade600,
onTap: () => Get.to(() => const SettingsCaptain())),
];
@override
Widget build(BuildContext context) {
return Drawer(
child: Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: Column(
children: [
// --- الجزء العلوي من القائمة (بيانات المستخدم) ---
UserHeader(), // استخدمنا الويدجت المحسنة بالأسفل
// --- قائمة العناصر المتحركة ---
Expanded(
child: AnimationLimiter(
child: ListView.builder(
padding: const EdgeInsets.all(8.0),
itemCount: drawerItems.length + 1, // +1 لزر تسجيل الخروج
itemBuilder: (BuildContext context, int index) {
// --- زر تسجيل الخروج في النهاية ---
if (index == drawerItems.length) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 375),
child: SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: _DrawerItemTile(
item: DrawerItem(
title: 'Sign Out'.tr,
icon: Icons.logout,
color: Colors.red,
onTap: () =>
Get.to(() => const LogoutCaptain())),
),
),
),
);
}
// --- بقية العناصر ---
final item = drawerItems[index];
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 375),
child: SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: _DrawerItemTile(item: item),
),
),
);
},
),
),
),
],
),
),
);
}
}
// --- ويدجت خاصة بكل عنصر في القائمة ---
class _DrawerItemTile extends StatelessWidget {
final DrawerItem item;
const _DrawerItemTile({required this.item});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: ListTile(
leading: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: item.color.withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(item.icon, color: item.color, size: 24),
),
title: Text(
item.title,
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.w500),
),
onTap: () {
Get.back(); // لإغلاق القائمة عند الضغط
Future.delayed(const Duration(milliseconds: 250), () {
item.onTap(); // الانتقال للصفحة بعد تأخير بسيط لإظهار الأنيميشن
});
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
splashColor: item.color.withOpacity(0.2),
),
);
}
}
// --- ويدجت محسنة للجزء العلوي من القائمة ---
// ... (الاستيرادات السابقة تبقى كما هي)
// --- تم تعديل UserHeader لإضافة التحقق من الصورة ---
class UserHeader extends StatelessWidget {
UserHeader({super.key});
final ImageController imageController = Get.find<ImageController>();
final HomeCaptainController homeCaptainController =
Get.find<HomeCaptainController>();
// دالة لإظهار التنبيه
void _showUploadPhotoDialog(
BuildContext context, ImageController controller) {
// نستخدم addPostFrameCallback لضمان عدم ظهور الخطأ أثناء بناء الواجهة
WidgetsBinding.instance.addPostFrameCallback((_) {
// نتأكد ألا يكون هناك dialog مفتوح بالفعل لتجنب التكرار
if (Get.isDialogOpen == true) return;
Get.defaultDialog(
title: "Profile Photo Required".tr,
titleStyle:
const TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
middleText:
"Please upload a clear photo of your face to be identified by passengers."
.tr,
barrierDismissible: false, // منع الإغلاق بالضغط خارج النافذة
radius: 15,
contentPadding: const EdgeInsets.all(20),
confirm: ElevatedButton.icon(
onPressed: () {
Get.back(); // إغلاق النافذة الحالية
// فتح الكاميرا فوراً
controller.choosImagePicture(
AppLink.uploadImagePortrate, 'portrait');
},
icon: const Icon(Icons.camera_alt, color: Colors.white),
label: Text("Take Photo Now".tr,
style: const TextStyle(color: Colors.white)),
style: ElevatedButton.styleFrom(
backgroundColor: AppColor
.primaryColor, // تأكد من وجود هذا اللون أو استبدله بـ Colors.blue
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
),
),
cancel: TextButton(
onPressed: () => Get.back(),
child: Text("Later".tr, style: const TextStyle(color: Colors.grey)),
),
);
});
}
@override
Widget build(BuildContext context) {
return UserAccountsDrawerHeader(
accountName: Text(
box.read(BoxName.nameDriver).toString(),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
shadows: [Shadow(blurRadius: 2, color: Colors.black26)]),
),
accountEmail:
box.read(BoxName.emailDriver).toString().contains('intaleqapp')
? Text('Your email not updated yet'.tr)
: Text(box.read(BoxName.emailDriver)),
currentAccountPicture: GetBuilder<ImageController>(
builder: (controller) => Stack(
clipBehavior: Clip.none,
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
boxShadow: [
BoxShadow(color: Colors.black.withOpacity(0.3), blurRadius: 5)
],
),
child: controller.isloading
? const CircularProgressIndicator(color: Colors.white)
: CircleAvatar(
// محاولة تحميل الصورة
backgroundImage: NetworkImage(
'${AppLink.server}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg'),
// [تعديل هام]: في حال فشل تحميل الصورة (غير موجودة)
onBackgroundImageError: (exception, stackTrace) {
// طباعة الخطأ في الكونسول للتوضيح
debugPrint(
"Profile image not found or error loading: $exception");
// استدعاء نافذة التنبيه
_showUploadPhotoDialog(context, controller);
},
// أيقونة بديلة تظهر في الخلفية إذا لم تكن الصورة موجودة
backgroundColor: Colors.grey.shade300,
child: const Icon(Icons.person,
size: 40, color: Colors.white),
),
),
Positioned(
bottom: -5,
right: -5,
child: InkWell(
onTap: () => controller.choosImagePicture(
AppLink.uploadImagePortrate, 'portrait'),
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Icon(Icons.camera_alt,
color: Theme.of(context).primaryColor, size: 18),
),
),
),
],
),
),
otherAccountsPictures: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
homeCaptainController.rating.toString(),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16),
),
const SizedBox(width: 4),
const Icon(Icons.star, color: Colors.amber, size: 20),
],
),
],
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Theme.of(context).primaryColor, Colors.blue.shade700],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
);
}
}