Files
intaleq_admin/lib/views/admin/drivers/driver_documents_review_page.dart
2026-05-02 15:16:30 +03:00

219 lines
8.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/colors.dart';
import '../../../constant/style.dart';
import '../../../controller/admin/driver_docs_controller.dart';
import '../../widgets/my_scafold.dart';
import '../../widgets/elevated_btn.dart';
import '../../../constant/links.dart';
class DriverDocsReviewPage extends StatelessWidget {
DriverDocsReviewPage({super.key});
final DriverDocsController controller = Get.put(DriverDocsController());
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'مراجعة طلبات التسجيل'.tr,
isleading: true,
body: [
Obx(() => controller.isLoading.value && controller.pendingDrivers.isEmpty
? const Center(child: CircularProgressIndicator())
: controller.pendingDrivers.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.how_to_reg_rounded, size: 64, color: AppColor.textMuted),
const SizedBox(height: 16),
Text('لا يوجد طلبات تسجيل حالياً', style: AppStyle.subtitle),
],
),
)
: RefreshIndicator(
onRefresh: () => controller.getPendingDrivers(),
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (!controller.isLoading.value &&
!controller.isMoreLoading.value &&
scrollInfo.metrics.pixels >= scrollInfo.metrics.maxScrollExtent - 200) {
controller.loadMore();
}
return false;
},
child: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: controller.pendingDrivers.length + (controller.hasMore.value ? 1 : 0),
itemBuilder: (context, index) {
if (index == controller.pendingDrivers.length) {
return const Padding(
padding: EdgeInsets.all(16.0),
child: Center(child: CircularProgressIndicator()),
);
}
final driver = controller.pendingDrivers[index];
return _buildDriverCard(context, driver);
},
),
),
)),
],
);
}
Widget _buildDriverCard(BuildContext context, dynamic driver) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
decoration: AppStyle.cardDecoration,
child: ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
leading: CircleAvatar(
backgroundColor: AppColor.accentSoft,
child: Text(driver['first_name']?[0] ?? 'D', style: const TextStyle(color: AppColor.accent)),
),
title: Text('${driver['first_name']} ${driver['last_name']}', style: AppStyle.title),
subtitle: Text(driver['phone'] ?? '', style: AppStyle.caption),
trailing: const Icon(Icons.arrow_forward_ios_rounded, size: 16, color: AppColor.textSecondary),
onTap: () => _showDriverDetails(context, driver['id'].toString()),
),
);
}
void _showDriverDetails(BuildContext context, String id) async {
final details = await controller.getDriverFullDetails(id);
if (details == null) return;
final driver = details['driver'];
final List docs = details['documents'];
Get.to(() => MyScafolld(
title: 'تفاصيل السائق',
isleading: true,
body: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDriverHeader(driver),
const SizedBox(height: 24),
Text('الوثائق المرفوعة', style: AppStyle.title),
const SizedBox(height: 12),
...docs.map((doc) => _buildDocCard(doc)).toList(),
const SizedBox(height: 32),
MyElevatedButton(
title: 'اعتماد وتفعيل الحساب',
icon: Icons.check_circle_rounded,
kolor: AppColor.success,
onPressed: () async {
bool success = await controller.approveDriver(id);
if (success) {
Get.back();
Get.snackbar('نجاح', 'تم تفعيل حساب السائق بنجاح');
}
},
),
const SizedBox(height: 100),
],
),
),
],
));
}
Widget _buildDriverHeader(dynamic driver) {
return Container(
padding: const EdgeInsets.all(20),
decoration: AppStyle.elevatedCard,
child: Column(
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${driver['first_name']} ${driver['last_name']}', style: AppStyle.headTitle),
Text(driver['phone'] ?? '', style: AppStyle.subtitle),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: AppColor.warning.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: Text('Pending', style: AppStyle.caption.copyWith(color: AppColor.warning)),
),
],
),
const Divider(height: 32, color: AppColor.divider),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildSmallInfo('الرقم الوطني', driver['national_number'] ?? 'N/A'),
_buildSmallInfo('الجنس', driver['gender'] ?? 'N/A'),
_buildSmallInfo('تاريخ الميلاد', driver['birthdate'] ?? 'N/A'),
],
),
],
),
);
}
Widget _buildSmallInfo(String label, String value) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: AppStyle.caption.copyWith(fontSize: 10)),
const SizedBox(height: 2),
Text(value, style: AppStyle.body.copyWith(fontSize: 12, fontWeight: FontWeight.bold)),
],
);
}
Widget _buildDocCard(dynamic doc) {
String imageUrl = doc['link'] ?? '';
// Ensure URL is absolute
if (!imageUrl.startsWith('http')) {
imageUrl = '${AppLink.server}/upload/drivers/$imageUrl';
}
return Container(
margin: const EdgeInsets.only(bottom: 16),
decoration: AppStyle.cardDecoration,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
const Icon(Icons.file_present_rounded, color: AppColor.accent, size: 20),
const SizedBox(width: 8),
Text(doc['doc_type'] ?? 'وثيقة', style: AppStyle.title.copyWith(fontSize: 14)),
],
),
),
ClipRRect(
borderRadius: const BorderRadius.vertical(bottom: Radius.circular(16)),
child: Image.network(
imageUrl,
width: double.infinity,
height: 200,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) => Container(
height: 200,
color: AppColor.surfaceElevated,
child: const Center(child: Icon(Icons.broken_image_rounded, size: 48, color: AppColor.textMuted)),
),
),
),
],
),
);
}
}