Files
Siro/siro_admin/lib/views/transit/org_details_page.dart
T

171 lines
6.4 KiB
Dart

// org_details_page.dart — تفاصيل وتحليلات مؤسسة (لوحة إدارة سيرو)
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/colors.dart';
import '../../controller/transit/transit_admin_controller.dart';
import 'org_admins_page.dart';
class TransitOrgDetailsPage extends StatefulWidget {
final int orgId;
final String orgName;
const TransitOrgDetailsPage({super.key, required this.orgId, required this.orgName});
@override
State<TransitOrgDetailsPage> createState() => _TransitOrgDetailsPageState();
}
class _TransitOrgDetailsPageState extends State<TransitOrgDetailsPage> {
@override
void initState() {
super.initState();
Get.find<TransitAdminController>().loadOrgDetails(widget.orgId);
}
@override
Widget build(BuildContext context) {
return GetBuilder<TransitAdminController>(
builder: (c) => Scaffold(
backgroundColor: AppColor.bg,
appBar: AppBar(
backgroundColor: AppColor.bg,
elevation: 0,
title: Text(widget.orgName, style: const TextStyle(color: AppColor.textPrimary)),
actions: [
IconButton(
tooltip: 'إدارة المشرفين',
icon: const Icon(Icons.admin_panel_settings_outlined, color: AppColor.accent),
onPressed: () => Get.to(
() => TransitOrgAdminsPage(orgId: widget.orgId, orgName: widget.orgName),
),
),
],
),
body: c.isLoadingDetails
? const Center(child: CircularProgressIndicator(color: AppColor.accent))
: c.selectedOrgDetails == null
? const Center(
child: Text('تعذّر تحميل البيانات', style: TextStyle(color: AppColor.textSecondary)))
: _content(c),
),
);
}
Widget _content(TransitAdminController c) {
final d = c.selectedOrgDetails!;
final counts = d.counts;
final trips = d.trips;
return ListView(
padding: const EdgeInsets.all(16),
children: [
_sectionTitle('الأسطول'),
Row(
children: [
_statCard('السائقون', '${counts['drivers_active'] ?? 0}/${counts['drivers_total'] ?? 0}',
Icons.badge_outlined),
const SizedBox(width: 10),
_statCard('المركبات', '${counts['vehicles_active'] ?? 0}/${counts['vehicles_total'] ?? 0}',
Icons.directions_bus_outlined),
],
),
const SizedBox(height: 10),
Row(
children: [
_statCard('الخطوط النشطة', '${counts['routes_active'] ?? 0}', Icons.route_outlined),
const SizedBox(width: 10),
_statCard('عضويات نشطة', '${counts['enrollments_active'] ?? 0}', Icons.people_outline),
],
),
if ((int.tryParse(counts['enrollments_pending']?.toString() ?? '0') ?? 0) > 0) ...[
const SizedBox(height: 10),
_statCard('طلبات بانتظار الموافقة', '${counts['enrollments_pending']}',
Icons.pending_actions_outlined, color: AppColor.warning),
],
const SizedBox(height: 24),
_sectionTitle('الرحلات'),
Row(
children: [
_statCard('اليوم', '${trips['today'] ?? 0}', Icons.today_outlined),
const SizedBox(width: 10),
_statCard('هذا الأسبوع', '${trips['this_week'] ?? 0}', Icons.date_range_outlined),
],
),
const SizedBox(height: 10),
Row(
children: [
_statCard('هذا الشهر', '${trips['this_month'] ?? 0}', Icons.calendar_month_outlined),
const SizedBox(width: 10),
_statCard('ساعات القيادة', '${trips['total_hours_driven'] ?? 0}', Icons.timer_outlined),
],
),
const SizedBox(height: 10),
Row(
children: [
_statCard('مكتملة', '${trips['completed'] ?? 0}', Icons.check_circle_outline,
color: AppColor.success),
const SizedBox(width: 10),
_statCard('متوسط التأخير', '${trips['avg_delay_minutes'] ?? 0} د', Icons.timelapse,
color: AppColor.warning),
],
),
const SizedBox(height: 24),
_sectionTitle('الخطوط'),
...d.routes.map((r) => Card(
color: AppColor.surface,
margin: const EdgeInsets.only(bottom: 8),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: ListTile(
title: Text(r['name_ar']?.toString() ?? '',
style: const TextStyle(color: AppColor.textPrimary)),
subtitle: Text(
'${r['stops_count'] ?? 0} محطة · ${r['completed_trips'] ?? 0} رحلة مكتملة',
style: const TextStyle(color: AppColor.textSecondary, fontSize: 12),
),
trailing: Text(
r['status']?.toString() ?? '',
style: TextStyle(
color: r['status'] == 'active' ? AppColor.success : AppColor.textSecondary,
fontSize: 12,
),
),
),
)),
],
);
}
Widget _sectionTitle(String text) => Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Text(text,
style: const TextStyle(
color: AppColor.textPrimary, fontSize: 16, fontWeight: FontWeight.bold)),
);
Widget _statCard(String label, String value, IconData icon, {Color? color}) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColor.surface,
borderRadius: BorderRadius.circular(14),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, color: color ?? AppColor.accent, size: 20),
const SizedBox(height: 8),
Text(value,
style: TextStyle(
color: color ?? AppColor.textPrimary,
fontSize: 18,
fontWeight: FontWeight.bold)),
const SizedBox(height: 2),
Text(label, style: const TextStyle(color: AppColor.textSecondary, fontSize: 11)),
],
),
),
);
}
}