// fuel_drawdowns_page.dart — حركة القسائم وملخّص الائتمان // // ‏الشاشة التي تُجيب: كم أقرضنا؟ كم استُرد؟ وكم بقي في الشارع؟ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../controller/fuel/fuel_admin_controller.dart'; import '../../../controller/fuel/fuel_admin_models.dart'; class FuelDrawdownsPageView extends StatefulWidget { const FuelDrawdownsPageView({super.key}); @override State createState() => _FuelDrawdownsPageViewState(); } class _FuelDrawdownsPageViewState extends State { String? _status; @override void initState() { super.initState(); Get.find().fetchDrawdowns(); } @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; return GetBuilder( builder: (c) => Scaffold( backgroundColor: cs.surface, appBar: AppBar( backgroundColor: cs.surface, foregroundColor: cs.onSurface, title: const Text('حركة القسائم'), ), body: Column( children: [ if (c.drawdowns != null) _summary(c.drawdowns!, cs), _filters(c, cs), Expanded( child: c.isLoadingDrawdowns ? Center(child: CircularProgressIndicator(color: cs.primary)) : (c.drawdowns?.vouchers.isEmpty ?? true) ? Center( child: Text('لا توجد قسائم', style: TextStyle(color: cs.onSurfaceVariant))) : ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 12), itemCount: c.drawdowns!.vouchers.length, itemBuilder: (_, i) => _voucherCard(c.drawdowns!.vouchers[i], cs), ), ), ], ), ), ); } /// ‏الملخّص على كامل المنتج لا على القائمة المعروضة: رقم يتغيّر بتغيّر /// ‏الفلتر يُقرأ كأنه حقيقة عن المنصة وهو ليس كذلك. Widget _summary(FuelDrawdownsPage d, ColorScheme cs) => Container( margin: const EdgeInsets.fromLTRB(12, 12, 12, 4), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: cs.surfaceContainerHighest, borderRadius: BorderRadius.circular(14), ), child: Row( children: [ _stat('أُقرض', d.lentTotal.toString(), cs.onSurface, cs), _stat('استُرد', d.collectedTotal.toString(), cs.primary, cs), _stat('قائم', d.outstandingTotal.toString(), cs.tertiary, cs), _stat('سائق', d.driversCount.toString(), cs.onSurfaceVariant, cs), ], ), ); Widget _stat(String label, String value, Color color, ColorScheme cs) => Expanded( child: Column( children: [ Text(value, style: TextStyle( color: color, fontSize: 16, fontWeight: FontWeight.w700)), const SizedBox(height: 2), Text(label, style: TextStyle(color: cs.onSurfaceVariant, fontSize: 11)), ], ), ); Widget _filters(FuelAdminController c, ColorScheme cs) { const options = { null: 'الكل', 'issued': 'سارية', 'redeemed': 'مصروفة', 'expired': 'منتهية', 'cancelled': 'ملغاة', }; return SizedBox( height: 46, child: ListView( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), children: options.entries.map((e) { final selected = _status == e.key; return Padding( padding: const EdgeInsets.only(left: 8), child: ChoiceChip( label: Text(e.value), selected: selected, onSelected: (_) { setState(() => _status = e.key); c.fetchDrawdowns(status: e.key); }, ), ); }).toList(), ), ); } Widget _voucherCard(FuelVoucher v, ColorScheme cs) { final (color, label) = switch (v.status) { 'redeemed' => (cs.primary, 'مصروفة'), 'issued' => (cs.tertiary, 'سارية'), 'cancelled' => (cs.error, 'ملغاة'), _ => (cs.onSurfaceVariant, 'منتهية'), }; // ‏المصروف لا المأذون: السائق قد يطلب عشرين ويتزوّد بخمسة عشر، // ‏والدَّين على ما صُرف. عرض المأذون هنا يضخّم الأرقام في عين القارئ. final amount = v.status == 'redeemed' ? v.amountRedeemed : v.amountAuthorized; return Card( color: cs.surfaceContainerHighest, margin: const EdgeInsets.only(bottom: 8), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: ListTile( title: Row( children: [ Text('$amount ${v.currency}', style: TextStyle( color: cs.onSurface, fontWeight: FontWeight.bold)), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: color.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(6), ), child: Text(label, style: TextStyle(color: color, fontSize: 11)), ), ], ), subtitle: Padding( padding: const EdgeInsets.only(top: 4), child: Text( [ 'سائق ${v.driverId}', if (v.station != null && v.station!.isNotEmpty) v.station!, v.redeemedAt ?? v.createdAt ?? '', ].where((s) => s.isNotEmpty).join(' · '), style: TextStyle(color: cs.onSurfaceVariant, fontSize: 11), ), ), ), ); } }