219 lines
8.4 KiB
Dart
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)),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|