Update Saqel Platform: 2026-09-04 21:26:55
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../core/theme/super_admin_theme.dart';
|
||||
import '../../logic/cubits/super_admin_cubit.dart';
|
||||
import '../../logic/cubits/super_admin_state.dart';
|
||||
import '../../logic/cubits/treasury_cubit.dart';
|
||||
import 'tabs/macro_radar_tab.dart';
|
||||
import 'tabs/ai_cluster_tab.dart';
|
||||
import 'tabs/treasury_cliq_tab.dart';
|
||||
import 'tabs/security_integrity_tab.dart';
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* SAQEL SOVEREIGN COMMAND - SUPER ADMIN SHELL
|
||||
* ==============================================================================
|
||||
*
|
||||
* الهيكل التنفيذي الرئيسي لتطبيق SuperAdmin الخاص بالمؤسس والمهندس المعماري التقني
|
||||
* (حمزة العائد / Hamza Ayed) - يوفر تنقلاً سلساً وفورياً بين أركان القيادة الأربعة:
|
||||
* 1. الرادار السيادي الكلي (مديريات، مدارس، اقتصاديات الوحدة، وهوامش الربح)
|
||||
* 2. عنقود الذكاء الاصطناعي المحلي (استهلاك VRAM، نماذج Qwen و DeepSeek)
|
||||
* 3. الخزينة وسحوبات كليك (الرصيد المركزي، الاعتماد الجماعي الفوري)
|
||||
* 4. النزاهة السيبرانية والأكاديمية (AES-256-GCM، فحص الترفع، كشف الشذوذ، Kill-Switch)
|
||||
*/
|
||||
class SuperAdminShell extends StatefulWidget {
|
||||
const SuperAdminShell({super.key});
|
||||
|
||||
@override
|
||||
State<SuperAdminShell> createState() => _SuperAdminShellState();
|
||||
}
|
||||
|
||||
class _SuperAdminShellState extends State<SuperAdminShell> {
|
||||
int _currentIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<SuperAdminCubit>().loadDashboard();
|
||||
context.read<TreasuryCubit>().loadTreasury();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Scaffold(
|
||||
backgroundColor: SuperAdminTheme.backgroundDark,
|
||||
appBar: AppBar(
|
||||
backgroundColor: SuperAdminTheme.surfaceDark,
|
||||
elevation: 0,
|
||||
toolbarHeight: 74,
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.royalGold.withOpacity(0.15),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(CupertinoIcons.shield_lefthalf_fill, color: SuperAdminTheme.royalGold, size: 18),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'صاقل | القيادة السيادية العليا',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.emeraldGreen.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: SuperAdminTheme.emeraldGreen.withOpacity(0.3)),
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircleAvatar(radius: 3, backgroundColor: SuperAdminTheme.emeraldGreen),
|
||||
SizedBox(width: 5),
|
||||
Text('Sovereign Live', style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: SuperAdminTheme.emeraldGreen)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
const Text(
|
||||
'المؤسس والمهندس المعماري: حمزة العائد (Hamza Ayed)',
|
||||
style: TextStyle(fontSize: 11.5, color: Colors.white60),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(CupertinoIcons.arrow_clockwise, color: SuperAdminTheme.cyberCyan, size: 20),
|
||||
tooltip: 'تحديث المؤشرات السيادية',
|
||||
onPressed: () {
|
||||
context.read<SuperAdminCubit>().loadDashboard();
|
||||
context.read<TreasuryCubit>().loadTreasury();
|
||||
},
|
||||
),
|
||||
],
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(1),
|
||||
child: Container(color: Colors.white.withOpacity(0.08), height: 1),
|
||||
),
|
||||
),
|
||||
body: BlocBuilder<SuperAdminCubit, SuperAdminState>(
|
||||
builder: (context, state) {
|
||||
if (state is SuperAdminLoading) {
|
||||
return const Center(
|
||||
child: CupertinoActivityIndicator(color: SuperAdminTheme.cyberCyan, radius: 16),
|
||||
);
|
||||
}
|
||||
|
||||
if (state is SuperAdminError) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(CupertinoIcons.exclamationmark_triangle, color: SuperAdminTheme.crimsonRed, size: 48),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
state.message,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 13),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
CupertinoButton(
|
||||
color: SuperAdminTheme.cyberCyan,
|
||||
onPressed: () => context.read<SuperAdminCubit>().loadDashboard(),
|
||||
child: const Text('إعادة المحاولة', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (state is SuperAdminLoaded) {
|
||||
return IndexedStack(
|
||||
index: _currentIndex,
|
||||
children: [
|
||||
MacroRadarTab(telemetry: state.telemetry),
|
||||
AiClusterTab(nodes: state.aiNodes),
|
||||
const TreasuryCliqTab(),
|
||||
SecurityIntegrityTab(
|
||||
alerts: state.alerts,
|
||||
isKillSwitchActive: state.isEmergencyKillSwitchActive,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceDark,
|
||||
border: Border(top: BorderSide(color: Colors.white.withOpacity(0.08), width: 1)),
|
||||
),
|
||||
child: BottomNavigationBar(
|
||||
currentIndex: _currentIndex,
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
selectedItemColor: SuperAdminTheme.royalGold,
|
||||
unselectedItemColor: Colors.white38,
|
||||
type: BottomNavigationBarType.fixed,
|
||||
selectedFontSize: 11,
|
||||
unselectedFontSize: 10,
|
||||
onTap: (index) => setState(() => _currentIndex = index),
|
||||
items: const [
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.chart_bar_alt_fill),
|
||||
activeIcon: Icon(CupertinoIcons.chart_bar_alt_fill, color: SuperAdminTheme.royalGold),
|
||||
label: 'الرصد الكلي',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.cpu),
|
||||
activeIcon: Icon(CupertinoIcons.cpu, color: SuperAdminTheme.royalGold),
|
||||
label: 'الذكاء المحلي',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.money_dollar_circle_fill),
|
||||
activeIcon: Icon(CupertinoIcons.money_dollar_circle_fill, color: SuperAdminTheme.royalGold),
|
||||
label: 'الخزينة وكليك',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.shield_lefthalf_fill),
|
||||
activeIcon: Icon(CupertinoIcons.shield_lefthalf_fill, color: SuperAdminTheme.royalGold),
|
||||
label: 'النزاهة والأمان',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../core/theme/super_admin_theme.dart';
|
||||
import '../../../data/models/super_admin_models.dart';
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* SAQEL SOVEREIGN COMMAND - LOCAL AI & GPU CLUSTER TAB
|
||||
* ==============================================================================
|
||||
*
|
||||
* رصد فوري لعناقيد الذكاء الاصطناعي السيادي المحلي:
|
||||
* - نماذج Qwen 2.5-VL (تحليل ومراجعة كراسات الحصص والمحتوى المرئي)
|
||||
* - نموذج DeepSeek-R1 (المحاكمة المنطقية والاستدلال التربوي والردود السقراطية)
|
||||
* - قياس استهلاك الذاكرة الرسومية VRAM وزمن الاستجابة (Latency ms)
|
||||
* - ضمان السيادة الرقمية التامة (Zero-Egress Sovereignty) بدون تسريب أي بيانات للخارج.
|
||||
*/
|
||||
class AiClusterTab extends StatelessWidget {
|
||||
final List<AiClusterNodeModel> nodes;
|
||||
|
||||
const AiClusterTab({super.key, required this.nodes});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Sovereign AI Sovereignty Moat Card
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF0F172A), Color(0xFF1E293B)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: SuperAdminTheme.cyberCyan.withOpacity(0.4)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: SuperAdminTheme.cyberCyan.withOpacity(0.12),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 6),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.cpu, color: SuperAdminTheme.cyberCyan, size: 22),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'عنقود الذكاء الاصطناعي السيادي (Local Inference)',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.emeraldGreen.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Text(
|
||||
'100% Zero-Egress',
|
||||
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold, color: SuperAdminTheme.emeraldGreen),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
'يعمل هذا العنقود داخل البنية التحتية الوطنية المغلقة. يتم معالجة تسجيلات الحصص المدرسية وكراسات التقييم باستخدام نماذج Qwen 2.5-VL و DeepSeek-R1 دون خروج أي بايت إلى خوادم أجنبية.',
|
||||
style: TextStyle(fontSize: 12.5, color: Colors.white70, height: 1.5),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
_buildQuickMetric('إجمالي العقد النشطة', '${nodes.length} عقد مخصصة', CupertinoIcons.layers_alt_fill),
|
||||
const SizedBox(width: 12),
|
||||
_buildQuickMetric('متوسط زمن الاستجابة', '120 ms', CupertinoIcons.bolt_fill),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Nodes List Section Title
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.circle_grid_hex_fill, color: SuperAdminTheme.royalGold, size: 18),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'حالة عقد المعالجة الرسومية (GPU Nodes Telemetry)',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Render Nodes
|
||||
...nodes.map((node) => _buildNodeCard(node)),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Inference Model Architecture Guide
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Colors.white10),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'توزيع مهام النماذج المتخصصة:',
|
||||
style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_buildModelArchitectureRow(
|
||||
'Qwen 2.5-VL 7B / 72B',
|
||||
'تحليل كراسات الطلاب، تدقيق فيديوهات الحصص (MIT 20-25 Min Limit)، واستخراج الرسوم التوضيحية.',
|
||||
SuperAdminTheme.cyberCyan,
|
||||
),
|
||||
const Divider(color: Colors.white10, height: 20),
|
||||
_buildModelArchitectureRow(
|
||||
'DeepSeek-R1 (Distill / Dense)',
|
||||
'الاستدلال الرياضي المتقدم، المحاكمة المنطقية، وبناء الحوارات السقراطية لغرف التساؤلات المدرسية.',
|
||||
SuperAdminTheme.imperialPurple,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildQuickMetric(String label, String value, IconData icon) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.white12),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon, size: 18, color: SuperAdminTheme.cyberCyan),
|
||||
const SizedBox(width: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: const TextStyle(fontSize: 11, color: Colors.white54)),
|
||||
const SizedBox(height: 2),
|
||||
Text(value, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold, color: Colors.white)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildNodeCard(AiClusterNodeModel node) {
|
||||
final double vramPercentage = (node.gpuVramUsageGb / node.gpuTotalVramGb).clamp(0.0, 1.0);
|
||||
final Color progressColor = vramPercentage > 0.85
|
||||
? SuperAdminTheme.crimsonRed
|
||||
: (vramPercentage > 0.65 ? SuperAdminTheme.royalGold : SuperAdminTheme.emeraldGreen);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Colors.white12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(
|
||||
color: node.status == 'active_online' ? SuperAdminTheme.emeraldGreen : SuperAdminTheme.royalGold,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: (node.status == 'active_online' ? SuperAdminTheme.emeraldGreen : SuperAdminTheme.royalGold).withOpacity(0.6),
|
||||
blurRadius: 6,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
node.nodeName,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black45,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
border: Border.all(color: Colors.white12),
|
||||
),
|
||||
child: Text(
|
||||
'${node.latencyMs} ms',
|
||||
style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w600, color: SuperAdminTheme.cyberCyan),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'${node.modelName} • ${node.role}',
|
||||
style: const TextStyle(fontSize: 12, color: Colors.white70),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// VRAM Progress
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('استهلاك VRAM للبطاقة الرسومية', style: TextStyle(fontSize: 11.5, color: Colors.white54)),
|
||||
Text(
|
||||
'${node.gpuVramUsageGb.toStringAsFixed(1)} GB / ${node.gpuTotalVramGb.toStringAsFixed(0)} GB (${(vramPercentage * 100).toStringAsFixed(0)}%)',
|
||||
style: TextStyle(fontSize: 11.5, fontWeight: FontWeight.w600, color: progressColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: vramPercentage,
|
||||
minHeight: 6,
|
||||
backgroundColor: Colors.white10,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(progressColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildModelArchitectureRow(String model, String role, Color accentColor) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(CupertinoIcons.checkmark_seal_fill, size: 16, color: accentColor),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(model, style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold, color: accentColor)),
|
||||
const SizedBox(height: 2),
|
||||
Text(role, style: const TextStyle(fontSize: 11.5, color: Colors.white60, height: 1.4)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../core/theme/super_admin_theme.dart';
|
||||
import '../../../data/models/super_admin_models.dart';
|
||||
|
||||
class MacroRadarTab extends StatelessWidget {
|
||||
final MacroTelemetryModel telemetry;
|
||||
|
||||
const MacroRadarTab({super.key, required this.telemetry});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Unit Economics & Gross Margin Sovereign Moat Banner
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF1E1B4B), Color(0xFF0F172A)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: SuperAdminTheme.imperialPurple.withOpacity(0.5)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: SuperAdminTheme.imperialPurple.withOpacity(0.15),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 8),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.sparkles, color: SuperAdminTheme.royalGold, size: 20),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'حماية هوامش الربح ووحدة الاقتصاد (Unit Economics)',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.emeraldGreen.withOpacity(0.2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'هامش ربح ${telemetry.grossMarginPercent}%',
|
||||
style: const TextStyle(fontSize: 12.5, fontWeight: FontWeight.w900, color: SuperAdminTheme.emeraldGreen),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
const Text(
|
||||
'وفر معمارية صَقِل السيادية مقارنة بالمنصات التقليدية:\n'
|
||||
'• خفض تكلفة الخرائط والبث بمقدار 0.30 دولار لكل طالب.\n'
|
||||
'• استبدال اشتراكات السحابة الأجنبية بالذكاء الاصطناعي المحلي (Qwen/DeepSeek).\n'
|
||||
'• التخزين السيادي عبر كودك البث المشفر لتوفير آلاف الدنانير شهرياً.',
|
||||
style: TextStyle(fontSize: 12.5, color: Color(0xFFCBD5E1), height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Core Metric Tiles (2x2 Grid)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _metricCard(
|
||||
title: 'إجمالي المدارس',
|
||||
value: '${telemetry.totalSchools} مدرسة',
|
||||
subtitle: '43 ثقافة عسكرية + مجمعات خاصة',
|
||||
icon: CupertinoIcons.building_2_fill,
|
||||
color: SuperAdminTheme.cyberCyan,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _metricCard(
|
||||
title: 'الطلبة المسجلون',
|
||||
value: '${telemetry.totalStudents}',
|
||||
subtitle: '19,350 برقم وطني مشفر',
|
||||
icon: CupertinoIcons.person_3_fill,
|
||||
color: SuperAdminTheme.imperialPurple,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _metricCard(
|
||||
title: 'الكادر التعليمي',
|
||||
value: '${telemetry.totalTeachers} معلماً',
|
||||
subtitle: 'معتمدون ومصنفون بالجدارة',
|
||||
icon: CupertinoIcons.star_circle_fill,
|
||||
color: SuperAdminTheme.royalGold,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _metricCard(
|
||||
title: 'استقرار النظام',
|
||||
value: '${telemetry.uptimePercent}%',
|
||||
subtitle: 'خوادم سيادية بلا انقطاع',
|
||||
icon: CupertinoIcons.checkmark_shield_fill,
|
||||
color: SuperAdminTheme.emeraldGreen,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Directorate Matrix Overview
|
||||
Container(
|
||||
padding: const EdgeInsets.all(18),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(color: SuperAdminTheme.border),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'المظلات المركزية المعتمدة في المنظومة 🏛️',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_directorateRow(
|
||||
name: 'مديرية التربية والتعليم والثقافة العسكرية',
|
||||
schools: 43,
|
||||
students: 19350,
|
||||
badge: 'عقد مؤسسي سيادي',
|
||||
color: SuperAdminTheme.emeraldGreen,
|
||||
),
|
||||
const Divider(color: SuperAdminTheme.border, height: 20),
|
||||
_directorateRow(
|
||||
name: 'مجمعات المدارس الخاصة المعتمدة (النمو السحابي)',
|
||||
schools: 12,
|
||||
students: 4200,
|
||||
badge: 'سوق صَقِل المفتوح',
|
||||
color: SuperAdminTheme.cyberCyan,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _metricCard({
|
||||
required String title,
|
||||
required String value,
|
||||
required String subtitle,
|
||||
required IconData icon,
|
||||
required Color color,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: SuperAdminTheme.border),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(icon, color: color, size: 24),
|
||||
const SizedBox(height: 10),
|
||||
Text(title, style: const TextStyle(fontSize: 12, color: Color(0xFF94A3B8))),
|
||||
const SizedBox(height: 4),
|
||||
Text(value, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900, color: Colors.white)),
|
||||
const SizedBox(height: 2),
|
||||
Text(subtitle, style: const TextStyle(fontSize: 10.5, color: Color(0xFF64748B))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _directorateRow({
|
||||
required String name,
|
||||
required int schools,
|
||||
required int students,
|
||||
required String badge,
|
||||
required Color color,
|
||||
}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(name, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w700, color: Colors.white)),
|
||||
const SizedBox(height: 3),
|
||||
Text('$schools مدرسة · $students طالباً', style: const TextStyle(fontSize: 11, color: Color(0xFF94A3B8))),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(badge, style: TextStyle(fontSize: 11, fontWeight: FontWeight.w700, color: color)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../core/theme/super_admin_theme.dart';
|
||||
import '../../../data/models/super_admin_models.dart';
|
||||
import '../../../logic/cubits/super_admin_cubit.dart';
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* SAQEL SOVEREIGN COMMAND - CYBER & EXAM INTEGRITY TAB
|
||||
* ==============================================================================
|
||||
*
|
||||
* رادار النزاهة الأكاديمية والأمن السيبراني السيادي:
|
||||
* - تشفير الأرقام الوطنية AES-256-GCM وحماية السجلات من أي تسريب
|
||||
* - مراقبة فحص الترفع الصفي والتحقق من صلاحيات الدخول المؤسسي
|
||||
* - إنذارات فورية لمحاولات الغش وحل الاختبارات بسرعة مستحيلة فلكياً (Impossible Speed)
|
||||
* - زر الإغلاق السيادي الطارئ (Emergency Sovereign Kill-Switch).
|
||||
*/
|
||||
class SecurityIntegrityTab extends StatelessWidget {
|
||||
final List<SecurityIntegrityAlertModel> alerts;
|
||||
final bool isKillSwitchActive;
|
||||
|
||||
const SecurityIntegrityTab({
|
||||
super.key,
|
||||
required this.alerts,
|
||||
required this.isKillSwitchActive,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Emergency Kill-Switch Card
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: isKillSwitchActive ? SuperAdminTheme.crimsonRed.withOpacity(0.2) : SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: isKillSwitchActive ? SuperAdminTheme.crimsonRed : Colors.white12,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
isKillSwitchActive ? CupertinoIcons.exclamationmark_octagon_fill : CupertinoIcons.shield_fill,
|
||||
color: isKillSwitchActive ? SuperAdminTheme.crimsonRed : SuperAdminTheme.emeraldGreen,
|
||||
size: 32,
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
isKillSwitchActive ? 'وضع العزل الطارئ نشط (Kill-Switch Active)' : 'منظومة الدفاع السيادية تعمل بنجاح',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isKillSwitchActive ? SuperAdminTheme.crimsonRed : Colors.white,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
isKillSwitchActive
|
||||
? 'تم إيقاف استلام الطلبات الخارجية وتجميد جلسات الامتحانات احترازياً.'
|
||||
: 'جميع جلسات الاختبارات مشفرة وتخضع لرقابة النزاهة اللحظية.',
|
||||
style: const TextStyle(fontSize: 11.5, color: Colors.white60),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
CupertinoSwitch(
|
||||
value: isKillSwitchActive,
|
||||
activeColor: SuperAdminTheme.crimsonRed,
|
||||
onChanged: (val) {
|
||||
context.read<SuperAdminCubit>().toggleEmergencyKillSwitch();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Sovereign Encryption & Integrity Badges
|
||||
Row(
|
||||
children: [
|
||||
_buildSecurityStatBadge(
|
||||
'تشفير الأرقام الوطنية',
|
||||
'AES-256-GCM',
|
||||
'صفر تسريب بيانات',
|
||||
SuperAdminTheme.cyberCyan,
|
||||
CupertinoIcons.lock_shield_fill,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
_buildSecurityStatBadge(
|
||||
'بوابة الحصص والصفوف',
|
||||
'Grade-Gate 100%',
|
||||
'فصل تام للصفوف 8 - 12',
|
||||
SuperAdminTheme.emeraldGreen,
|
||||
CupertinoIcons.checkmark_seal_fill,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Security Incidents Header
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.shield_slash_fill, color: SuperAdminTheme.royalGold, size: 18),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'إنذارات النزاهة السيادية اللحظية',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.crimsonRed.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
'${alerts.length} إنذارات',
|
||||
style: const TextStyle(fontSize: 11, fontWeight: FontWeight.bold, color: SuperAdminTheme.crimsonRed),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Alerts List
|
||||
...alerts.map((alert) => _buildAlertCard(alert)),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Audit Log Integrity Explanation
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Colors.white10),
|
||||
),
|
||||
child: const Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.eye_solid, size: 16, color: SuperAdminTheme.cyberCyan),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'خوارزمية كشف الشذوذ الأكاديمي (Anomaly Detection):',
|
||||
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
'تقوم المنظومة بمقارنة زمن حل الطالب لكل سؤال رياضي بالحد الأدنى المعرفي. إذا تم تقديم اختبار يحتوي 30 مسألة تفاضل في أقل من 12 ثانية، يُصنف الاختبار فوراً كـ Anomaly ويتم تجميد العلامة لتدقيق المعلم والمشرف.',
|
||||
style: TextStyle(fontSize: 11.5, color: Colors.white60, height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSecurityStatBadge(String title, String value, String subtitle, Color color, IconData icon) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: color.withOpacity(0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(icon, color: color, size: 20),
|
||||
const SizedBox(height: 10),
|
||||
Text(value, style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: color)),
|
||||
const SizedBox(height: 2),
|
||||
Text(title, style: const TextStyle(fontSize: 11.5, fontWeight: FontWeight.w600, color: Colors.white)),
|
||||
const SizedBox(height: 2),
|
||||
Text(subtitle, style: const TextStyle(fontSize: 10, color: Colors.white54)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAlertCard(SecurityIntegrityAlertModel alert) {
|
||||
final bool isCritical = alert.severity == 'critical';
|
||||
final Color alertColor = isCritical ? SuperAdminTheme.crimsonRed : SuperAdminTheme.royalGold;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: alertColor.withOpacity(0.35)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
isCritical ? CupertinoIcons.exclamationmark_triangle_fill : CupertinoIcons.bell_fill,
|
||||
color: alertColor,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
alert.title,
|
||||
style: const TextStyle(fontSize: 13.5, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
alert.timeAgo,
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white38),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
'الموقع / المدرسة: ${alert.schoolName}',
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: SuperAdminTheme.cyberCyan),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
alert.details,
|
||||
style: const TextStyle(fontSize: 11.5, color: Colors.white70, height: 1.4),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../core/theme/super_admin_theme.dart';
|
||||
import '../../../data/models/super_admin_models.dart';
|
||||
import '../../../logic/cubits/treasury_cubit.dart';
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* SAQEL SOVEREIGN COMMAND - TREASURY & CLIQ PAYOUT QUEUE TAB
|
||||
* ==============================================================================
|
||||
*
|
||||
* إدارة الخزينة المركزية السيادية والموافقة الفورية على دفعات المعلمين عبر CliQ:
|
||||
* - رصيد الخزينة الإجمالي (54,200 دينار أردني)
|
||||
* - موافقة جماعية بنقرة واحدة (1-Click Mass Payout Approval)
|
||||
* - معالجة فورية عبر نمط Siro-Engine بدون عمولات وسيطة (Zero-Intermediary Fee)
|
||||
* - سجل تفصيلي لطلبات السحب المعلقة والمكتملة.
|
||||
*/
|
||||
class TreasuryCliqTab extends StatelessWidget {
|
||||
const TreasuryCliqTab({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<TreasuryCubit, TreasuryState>(
|
||||
builder: (context, state) {
|
||||
if (state is TreasuryLoading) {
|
||||
return const Center(
|
||||
child: CupertinoActivityIndicator(color: SuperAdminTheme.cyberCyan),
|
||||
);
|
||||
}
|
||||
|
||||
if (state is TreasuryLoaded) {
|
||||
final pendingItems = state.queue.where((item) => item.status == 'queued').toList();
|
||||
final completedItems = state.queue.where((item) => item.status == 'completed').toList();
|
||||
final double pendingSum = pendingItems.fold(0.0, (acc, item) => acc + item.amountJod);
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Sovereign Treasury Card
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF064E3B), Color(0xFF0F172A)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: SuperAdminTheme.emeraldGreen.withOpacity(0.5)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: SuperAdminTheme.emeraldGreen.withOpacity(0.18),
|
||||
blurRadius: 20,
|
||||
offset: const Offset(0, 8),
|
||||
)
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.money_dollar_circle_fill, color: SuperAdminTheme.emeraldGreen, size: 22),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'الخزينة السيادية المركزية (Sovereign Treasury)',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black38,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Text(
|
||||
'CliQ Direct Rail',
|
||||
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold, color: SuperAdminTheme.emeraldGreen),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'${state.totalTreasuryBalanceJod.toStringAsFixed(2)} د.أ',
|
||||
style: const TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const Text(
|
||||
'صافي السيولة النقدية المودعة والمحمية في الحساب المصرفي المركزي الموحد.',
|
||||
style: TextStyle(fontSize: 12, color: Colors.white70),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
_buildStatBadge('المعلق للسحب', '${pendingSum.toStringAsFixed(2)} د.أ', SuperAdminTheme.royalGold),
|
||||
const SizedBox(width: 10),
|
||||
_buildStatBadge('المصروف اليوم', '${state.totalApprovedTodayJod.toStringAsFixed(2)} د.أ', SuperAdminTheme.cyberCyan),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// 1-Click Mass Approval Action
|
||||
if (pendingItems.isNotEmpty)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(bottom: 20),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: SuperAdminTheme.royalGold.withOpacity(0.4)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.checkmark_shield_fill, color: SuperAdminTheme.royalGold, size: 26),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'يوجد ${pendingItems.length} طلبات سحب معلقة بقيمة ${pendingSum.toStringAsFixed(2)} د.أ',
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const Text(
|
||||
'يمكنك اعتماد وإرسال التحويلات فورياً عبر شبكة كليك المركزية.',
|
||||
style: TextStyle(fontSize: 11.5, color: Colors.white60),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
color: SuperAdminTheme.royalGold,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
onPressed: () {
|
||||
context.read<TreasuryCubit>().approveAllPayouts();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('تم اعتماد وصرف جميع مستحقات المعلمين بنجاح عبر شبكة CliQ!'),
|
||||
backgroundColor: SuperAdminTheme.emeraldGreen,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text(
|
||||
'اعتماد الكل',
|
||||
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold, color: Colors.black),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Payout Queue Section Header
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.arrow_right_arrow_left, color: SuperAdminTheme.cyberCyan, size: 18),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'طابور سحوبات المعلمين (Payout Queue)',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'${state.queue.length} عمليات',
|
||||
style: const TextStyle(fontSize: 12, color: Colors.white54),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// List Items
|
||||
...state.queue.map((item) => _buildPayoutCard(context, item)),
|
||||
|
||||
if (state.queue.isEmpty)
|
||||
Container(
|
||||
padding: const EdgeInsets.all(28),
|
||||
alignment: Alignment.center,
|
||||
child: const Text(
|
||||
'لا توجد طلبات سحب حالياً في الطابور.',
|
||||
style: TextStyle(color: Colors.white38, fontSize: 13),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatBadge(String label, String value, Color color) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(0.35),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.white12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: const TextStyle(fontSize: 11, color: Colors.white54)),
|
||||
const SizedBox(height: 2),
|
||||
Text(value, style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: color)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPayoutCard(BuildContext context, PayoutQueueItemModel item) {
|
||||
final bool isQueued = item.status == 'queued';
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.surfaceCard,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: isQueued ? SuperAdminTheme.royalGold.withOpacity(0.3) : Colors.white10,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: isQueued ? SuperAdminTheme.royalGold.withOpacity(0.15) : SuperAdminTheme.emeraldGreen.withOpacity(0.15),
|
||||
child: Icon(
|
||||
isQueued ? CupertinoIcons.clock_fill : CupertinoIcons.checkmark_alt,
|
||||
color: isQueued ? SuperAdminTheme.royalGold : SuperAdminTheme.emeraldGreen,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.teacherName,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'اسم مستعار كليك: ${item.cliqAlias} • ${item.requestedAt}',
|
||||
style: const TextStyle(fontSize: 11.5, color: Colors.white54),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'${item.amountJod.toStringAsFixed(2)} د.أ',
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
if (isQueued)
|
||||
CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
color: SuperAdminTheme.emeraldGreen,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
minSize: 26,
|
||||
onPressed: () {
|
||||
context.read<TreasuryCubit>().approvePayout(item.id);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('تم اعتماد تحويل ${item.amountJod} د.أ إلى المعلم ${item.teacherName} عبر CliQ'),
|
||||
backgroundColor: SuperAdminTheme.emeraldGreen,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text(
|
||||
'اعتماد',
|
||||
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold, color: Colors.black),
|
||||
),
|
||||
)
|
||||
else
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: SuperAdminTheme.emeraldGreen.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: const Text(
|
||||
'مكتمل ومحوّل',
|
||||
style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: SuperAdminTheme.emeraldGreen),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user