Files
Siro/siro_service/lib/controller/mainController/pages/complaint.dart
T

160 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:siro_service/views/widgets/my_scafold.dart';
import '../complaints/complaint_list_controller.dart';
import '../../../views/home/complaints/complaint_resolve_page.dart';
/// شاشة الشكاوى لموظف خدمة العملاء.
///
/// كانت هيكلاً فارغاً (`body: []`). الآن: قائمة مرتّبة بغير المحلول أولاً،
/// وتنبيه بالمتأخر، وفتح أداة التسوية بضغطة.
class Complaint extends StatelessWidget {
const Complaint({super.key});
@override
Widget build(BuildContext context) {
final c = Get.put(ComplaintListController());
final cs = Theme.of(context).colorScheme;
return MyScaffold(
title: "View complaint".tr,
isleading: true,
body: [
Obx(() {
if (c.isLoading.value && c.complaints.isEmpty) {
return const Padding(
padding: EdgeInsets.only(top: 60),
child: Center(child: CircularProgressIndicator()),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ‏المتأخر أولاً وبصرياً: رقم يجب ألا يكبر، فإخفاؤه في قائمة
// ‏طويلة يعني أن أحداً لن يلاحظه.
if (c.staleCount > 0)
Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: cs.error.withOpacity(0.08),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: cs.error.withOpacity(0.3)),
),
child: Row(children: [
Icon(Icons.warning_amber_rounded, color: cs.error, size: 20),
const SizedBox(width: 10),
Expanded(
child: Text(
'${c.staleCount} شكوى مفتوحة منذ أكثر من أسبوع',
style: TextStyle(
color: cs.error,
fontSize: 13,
fontWeight: FontWeight.bold),
),
),
]),
),
_Filters(c: c),
const SizedBox(height: 8),
if (c.visible.isEmpty)
const Padding(
padding: EdgeInsets.only(top: 60),
child: Center(child: Text('لا شكاوى')),
)
else
...c.visible.map((item) => _ComplaintTile(item: item, c: c)),
],
);
}),
],
);
}
}
class _Filters extends StatelessWidget {
const _Filters({required this.c});
final ComplaintListController c;
@override
Widget build(BuildContext context) {
const options = <String, String>{
'': 'الكل',
'Open': 'مفتوحة',
'In Progress': 'قيد المعالجة',
'Resolved': 'محلولة',
};
return Obx(() => Wrap(
spacing: 8,
children: options.entries
.map((e) => ChoiceChip(
label: Text(e.value, style: const TextStyle(fontSize: 12)),
selected: c.statusFilter.value == e.key,
onSelected: (_) => c.statusFilter.value = e.key,
))
.toList(),
));
}
}
class _ComplaintTile extends StatelessWidget {
const _ComplaintTile({required this.item, required this.c});
final Map<String, dynamic> item;
final ComplaintListController c;
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
final status = item['statusComplaint']?.toString() ?? 'Open';
final color = status == 'Resolved'
? Colors.green
: status == 'In Progress'
? Colors.orange
: cs.error;
return Card(
margin: const EdgeInsets.only(bottom: 10),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
child: ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
leading: Container(
width: 8,
height: 44,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(4),
),
),
title: Text(
item['description']?.toString().trim().isNotEmpty == true
? item['description'].toString()
: 'بدون وصف',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
'رحلة ${item['ride_id']} · ${item['complaint_type'] ?? 'عام'}'
' · ${item['date_filed'] ?? ''}',
style: TextStyle(fontSize: 11, color: cs.onSurfaceVariant),
),
),
trailing: Icon(Icons.chevron_left, color: cs.onSurfaceVariant),
onTap: () async {
final changed = await Get.to(
() => ComplaintResolvePage(complaint: item));
if (changed == true) c.fetch();
},
),
);
}
}