188 lines
7.2 KiB
Dart
188 lines
7.2 KiB
Dart
// org_admins_page.dart — متابعة إدارة المؤسسة وإضافة المشرفين (لوحة إدارة سيرو)
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import '../../constant/colors.dart';
|
|
import '../../controller/transit/transit_admin_controller.dart';
|
|
|
|
class TransitOrgAdminsPage extends StatefulWidget {
|
|
final int orgId;
|
|
final String orgName;
|
|
const TransitOrgAdminsPage({super.key, required this.orgId, required this.orgName});
|
|
|
|
@override
|
|
State<TransitOrgAdminsPage> createState() => _TransitOrgAdminsPageState();
|
|
}
|
|
|
|
class _TransitOrgAdminsPageState extends State<TransitOrgAdminsPage> {
|
|
final _name = TextEditingController();
|
|
final _phone = TextEditingController();
|
|
String _role = 'transport_manager';
|
|
|
|
final _roles = const {
|
|
'owner': 'مالك',
|
|
'transport_manager': 'مدير نقل',
|
|
'dispatcher': 'منسّق',
|
|
};
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
Get.find<TransitAdminController>().fetchOrgAdmins(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)),
|
|
),
|
|
floatingActionButton: FloatingActionButton(
|
|
backgroundColor: AppColor.accent,
|
|
onPressed: () => _showAddAdminSheet(context, c),
|
|
child: const Icon(Icons.person_add_alt_1, color: Colors.white),
|
|
),
|
|
body: c.isLoadingAdmins
|
|
? const Center(child: CircularProgressIndicator(color: AppColor.accent))
|
|
: c.orgAdmins.isEmpty
|
|
? const Center(
|
|
child: Text('لا يوجد مشرفون بعد', style: TextStyle(color: AppColor.textSecondary)))
|
|
: ListView.builder(
|
|
padding: const EdgeInsets.all(16),
|
|
itemCount: c.orgAdmins.length,
|
|
itemBuilder: (_, i) => _adminCard(c, c.orgAdmins[i]),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _adminCard(TransitAdminController c, Map<String, dynamic> admin) {
|
|
final isActive = admin['is_active'].toString() == '1';
|
|
return Card(
|
|
color: AppColor.surface,
|
|
margin: const EdgeInsets.only(bottom: 10),
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
|
child: ListTile(
|
|
leading: CircleAvatar(
|
|
backgroundColor: AppColor.accentSoft,
|
|
child: Icon(Icons.person, color: isActive ? AppColor.accent : AppColor.textMuted),
|
|
),
|
|
title: Text(admin['name']?.toString() ?? '',
|
|
style: const TextStyle(color: AppColor.textPrimary, fontWeight: FontWeight.bold)),
|
|
subtitle: Text(
|
|
'${admin['phone'] ?? ''} · ${_roles[admin['role']] ?? admin['role']}',
|
|
style: const TextStyle(color: AppColor.textSecondary, fontSize: 12),
|
|
),
|
|
trailing: Switch(
|
|
value: isActive,
|
|
activeThumbColor: AppColor.success,
|
|
onChanged: (v) => c.toggleOrgAdmin(widget.orgId, int.parse(admin['id'].toString()), v),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _showAddAdminSheet(BuildContext context, TransitAdminController c) {
|
|
_name.clear();
|
|
_phone.clear();
|
|
_role = 'transport_manager';
|
|
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
backgroundColor: AppColor.surface,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
|
),
|
|
builder: (ctx) => StatefulBuilder(
|
|
builder: (ctx, setSheetState) => GetBuilder<TransitAdminController>(
|
|
builder: (c) => Padding(
|
|
padding: EdgeInsets.only(
|
|
left: 20,
|
|
right: 20,
|
|
top: 20,
|
|
bottom: MediaQuery.of(ctx).viewInsets.bottom + 20,
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text('إضافة مشرف جديد',
|
|
style: TextStyle(
|
|
color: AppColor.textPrimary, fontSize: 18, fontWeight: FontWeight.bold)),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _name,
|
|
style: const TextStyle(color: AppColor.textPrimary),
|
|
decoration: _inputDecoration('اسم المشرف'),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _phone,
|
|
keyboardType: TextInputType.phone,
|
|
style: const TextStyle(color: AppColor.textPrimary),
|
|
decoration: _inputDecoration('رقم الهاتف'),
|
|
),
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<String>(
|
|
initialValue: _role,
|
|
dropdownColor: AppColor.surface,
|
|
style: const TextStyle(color: AppColor.textPrimary),
|
|
decoration: _inputDecoration('الصلاحية'),
|
|
items: _roles.entries
|
|
.map((e) => DropdownMenuItem(value: e.key, child: Text(e.value)))
|
|
.toList(),
|
|
onChanged: (v) => setSheetState(() => _role = v!),
|
|
),
|
|
const SizedBox(height: 20),
|
|
ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColor.accent,
|
|
minimumSize: const Size.fromHeight(48),
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
),
|
|
onPressed: c.isSavingAdmin
|
|
? null
|
|
: () async {
|
|
if (_name.text.trim().isEmpty || _phone.text.trim().isEmpty) {
|
|
Get.snackbar('مواصلاتي', 'الرجاء تعبئة كل الحقول');
|
|
return;
|
|
}
|
|
final ok = await c.addOrgAdmin(
|
|
orgId: widget.orgId,
|
|
name: _name.text.trim(),
|
|
phone: _phone.text.trim(),
|
|
role: _role,
|
|
);
|
|
if (ok && ctx.mounted) Navigator.pop(ctx);
|
|
},
|
|
child: c.isSavingAdmin
|
|
? const SizedBox(
|
|
height: 20, width: 20,
|
|
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white))
|
|
: const Text('إضافة', style: TextStyle(color: Colors.white)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
InputDecoration _inputDecoration(String label) => InputDecoration(
|
|
labelText: label,
|
|
labelStyle: const TextStyle(color: AppColor.textSecondary),
|
|
filled: true,
|
|
fillColor: AppColor.surfaceElevated,
|
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none),
|
|
);
|
|
}
|