Update Saqel Platform: 2026-09-04 03:09:10
This commit is contained in:
@@ -669,37 +669,81 @@ class _UnifiedHomeScreenState extends State<UnifiedHomeScreen> {
|
||||
const Divider(color: AppColors.darkCardBorder),
|
||||
const SizedBox(height: 10),
|
||||
_buildGuardianStat('الامتحانات المنجزة بنجاح', '${selectedChild.examsPassed} من ${selectedChild.examsTotal}'),
|
||||
_buildGuardianStat('الرقم الوطني', selectedChild.nationalId ?? 'مسجل بالهاتف'),
|
||||
_buildGuardianStat('دفتر الأخطاء الذكي', '8 من أصل 10 فجوات تم شفاؤها وإتقانها 🏆'),
|
||||
_buildGuardianStat('نسبة الحضور ومشاهدة الحصص', '96% (28 حصة مكتملة)'),
|
||||
_buildGuardianStat('الفحوصات السقراطية التفاعلية', '18 فحصاً مجتازاً بنجاح ✨'),
|
||||
_buildGuardianStat('الرقم الوطني المشفر', selectedChild.nationalId ?? 'مسجل بالهاتف'),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Real WhatsApp Reports Integration Banner
|
||||
LuxuryCard(
|
||||
backgroundColor: const Color(0xFF075E54).withAlpha(35),
|
||||
borderColor: AppColors.whatsappGreen.withAlpha(80),
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.chat_bubble_fill, color: AppColors.whatsappGreen, size: 24),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'تقارير بوابة نبيه للواتساب',
|
||||
style: TextStyle(fontSize: 13.5, fontWeight: FontWeight.w700, color: Colors.white),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
'تصلك إشعارات الأداء والغياب آلياً عبر رقم الواتساب المسجل',
|
||||
style: TextStyle(fontSize: 11, color: AppColors.textSecondaryDark),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: CupertinoAlertDialog(
|
||||
title: const Text('ومضة التقرير الشهري لولي الأمر 📲'),
|
||||
content: Text(
|
||||
'🇯🇴 تقرير التحصيل الأكاديمي لشهر آب/أيلول 2026\n'
|
||||
'الطالب: ${selectedChild.name}\n'
|
||||
'المدرسة: ${selectedChild.schoolName ?? "الثقافة العسكرية"}\n\n'
|
||||
'• مؤشر الجاهزية للتوجيهي: ${selectedChild.readinessScore.toStringAsFixed(1)}%\n'
|
||||
'• الحصص المكتملة: 28 حصة بنسبة التزام 96%\n'
|
||||
'• دفتر الأخطاء: تم إتقان 8 فجوات بنجاح\n'
|
||||
'• نتيجة الامتحان الموحد الأخير: 88%\n\n'
|
||||
'تم إرسال هذا التقرير عبر بوابة نبيه للواتساب برقم هاتف ولي الأمر.',
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
child: const Text('إغلاق'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: LuxuryCard(
|
||||
backgroundColor: const Color(0xFF075E54).withAlpha(45),
|
||||
borderColor: AppColors.whatsappGreen.withAlpha(90),
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.chat_bubble_2_fill, color: AppColors.whatsappGreen, size: 26),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'تقارير بوابة نبيه للواتساب 📲',
|
||||
style: TextStyle(fontSize: 13.5, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
Text(
|
||||
'· نشطة',
|
||||
style: TextStyle(color: Color(0xFF34D399), fontWeight: FontWeight.w700, fontSize: 11),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 3),
|
||||
Text(
|
||||
'انقر لمعاينة ومضة الأداء الأكاديمي الشهرية المرسلة لولي الأمر',
|
||||
style: TextStyle(fontSize: 11, color: AppColors.textSecondaryDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(CupertinoIcons.chevron_back, color: AppColors.whatsappGreen, size: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -141,6 +141,7 @@ class _TeacherMainShellState extends State<TeacherMainShell> {
|
||||
TeacherStudioUploadView(),
|
||||
TeacherMonetizationView(),
|
||||
TeacherReputationScorecardView(),
|
||||
TeacherAssignmentsAndQnAView(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: Container(
|
||||
@@ -155,8 +156,8 @@ class _TeacherMainShellState extends State<TeacherMainShell> {
|
||||
selectedItemColor: const Color(0xFF10B981),
|
||||
unselectedItemColor: const Color(0xFF64748B),
|
||||
selectedLabelStyle:
|
||||
const TextStyle(fontWeight: FontWeight.w800, fontSize: 12),
|
||||
unselectedLabelStyle: const TextStyle(fontSize: 11),
|
||||
const TextStyle(fontWeight: FontWeight.w800, fontSize: 11),
|
||||
unselectedLabelStyle: const TextStyle(fontSize: 10.5),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
elevation: 0,
|
||||
items: const [
|
||||
@@ -166,11 +167,15 @@ class _TeacherMainShellState extends State<TeacherMainShell> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.money_dollar_circle_fill),
|
||||
label: 'محفظة التسييل (55%)',
|
||||
label: 'محفظة التسييل',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.chart_bar_circle_fill),
|
||||
label: 'بطاقة الأداء والرادار',
|
||||
label: 'رادار الأداء',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(CupertinoIcons.chat_bubble_2_fill),
|
||||
label: 'الواجبات والأسئلة',
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1033,3 +1038,337 @@ class _ScoreStat extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// ==============================================================================
|
||||
/// TAB 4: TEACHER ASSIGNMENTS & STUDENT DOUBT CLEARING (Q&A & VOICE REPLIES)
|
||||
/// ==============================================================================
|
||||
class TeacherAssignmentsAndQnAView extends StatefulWidget {
|
||||
const TeacherAssignmentsAndQnAView({super.key});
|
||||
|
||||
@override
|
||||
State<TeacherAssignmentsAndQnAView> createState() =>
|
||||
_TeacherAssignmentsAndQnAViewState();
|
||||
}
|
||||
|
||||
class _TeacherAssignmentsAndQnAViewState
|
||||
extends State<TeacherAssignmentsAndQnAView> {
|
||||
final List<Map<String, dynamic>> _homeworks = [
|
||||
{
|
||||
'title': 'ورقة عمل: قوانين نيوتن وتطبيقات المصاعد',
|
||||
'class': 'الأول ثانوي العلمي (شعبة أ)',
|
||||
'submitted': '38 من 42 طالباً',
|
||||
'due_date': 'غداً الساعة 08:00 مساءً',
|
||||
'average_score': '86%',
|
||||
'status': 'active',
|
||||
},
|
||||
{
|
||||
'title': 'واجب بيتي: مسائل تحليل المتجهات والضرب القياسي',
|
||||
'class': 'الأول ثانوي العلمي (شعبة ب)',
|
||||
'submitted': '41 من 41 طالباً',
|
||||
'due_date': 'مكتمل التسليم والتصحيح الآلي',
|
||||
'average_score': '92%',
|
||||
'status': 'completed',
|
||||
},
|
||||
];
|
||||
|
||||
final List<Map<String, dynamic>> _studentDoubts = [
|
||||
{
|
||||
'student_name': 'محمد طارق الحنيطي',
|
||||
'class': 'الأول ثانوي العلمي',
|
||||
'question': 'أستاذ، لماذا ينعدم الوزن الظاهري في المصعد الساقط سقوطاً حراً؟ هل تفقد الأجسام كتلتها؟',
|
||||
'time': 'منذ 25 دقيقة',
|
||||
'replied': false,
|
||||
'voice_reply': false,
|
||||
},
|
||||
{
|
||||
'student_name': 'سيف الدين الرواشدة',
|
||||
'class': 'الأول ثانوي العلمي',
|
||||
'question': 'هل قوة الاحتكاك السكوني دائماً تساوي القوة المؤثرة حتى نصل للقيمة العظمى؟',
|
||||
'time': 'منذ ساعتين',
|
||||
'replied': true,
|
||||
'voice_reply': true,
|
||||
},
|
||||
];
|
||||
|
||||
void _dispatchNewHomework() {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: CupertinoAlertDialog(
|
||||
title: const Text('إسناد ورقة عمل تفاعلية جديدة 📝'),
|
||||
content: const Text(
|
||||
'سيقوم محرك صَقِل بتوليد ورقة عمل مكونة من 5 مسائل تدريبية متدرجة من بنك الأسئلة الوزاري وإرسالها فوراً لشعبتك مع التصحيح التلقائي.',
|
||||
),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
child: const Text('إلغاء'),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Navigator.of(ctx).pop();
|
||||
setState(() {
|
||||
_homeworks.insert(0, {
|
||||
'title': 'ورقة عمل: الشغل والطاقة الميكانيكية',
|
||||
'class': 'الأول ثانوي العلمي (شعبة أ وب)',
|
||||
'submitted': '0 من 83 طالباً',
|
||||
'due_date': 'الخميس القادم',
|
||||
'average_score': 'بانتظار الإجابات',
|
||||
'status': 'active',
|
||||
});
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('تم إسناد ورقة العمل وإشعار الطلبة بنجاح 🚀'),
|
||||
backgroundColor: Color(0xFF10B981),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('إسناد للطلبة الآن'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _recordVoiceReply(int doubtIndex) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (ctx) => Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFF0F172A),
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
|
||||
border: Border(top: BorderSide(color: Color(0xFF10B981), width: 2)),
|
||||
),
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(CupertinoIcons.mic_circle_fill, size: 56, color: Color(0xFF10B981)),
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
'تسجيل رد صوتي سقراطي للطالب 🎙️',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const Text(
|
||||
'سيصل التسجيل الصوتي بجودة عالية داخل تطبيق الطالب مع التوجيه المفاهيمي.',
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF94A3B8)),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
Navigator.of(ctx).pop();
|
||||
setState(() {
|
||||
_studentDoubts[doubtIndex]['replied'] = true;
|
||||
_studentDoubts[doubtIndex]['voice_reply'] = true;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('تم إرسال الرد الصوتي للطالب بنجاح 🎧'),
|
||||
backgroundColor: Color(0xFF10B981),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(CupertinoIcons.paperplane_fill, size: 16),
|
||||
label: const Text('إنهاء وإرسال التسجيل الصوتي (00:42)'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF10B981),
|
||||
foregroundColor: Colors.black,
|
||||
minimumSize: const Size(double.infinity, 44),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Top Action Card
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF064E3B), Color(0xFF0F172A)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: const Color(0xFF10B981).withOpacity(0.4)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'أوراق العمل والواجبات الوزارية 📝',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
SizedBox(height: 3),
|
||||
Text(
|
||||
'تصحيح مؤتمت بنسبة 100% مرتبط ببنك الأسئلة',
|
||||
style: TextStyle(fontSize: 11.5, color: Color(0xFF94A3B8)),
|
||||
),
|
||||
],
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: _dispatchNewHomework,
|
||||
icon: const Icon(CupertinoIcons.plus_circle_fill, size: 16),
|
||||
label: const Text('إسناد واجب جديد', style: TextStyle(fontSize: 12, fontWeight: FontWeight.w800)),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF10B981),
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Homeworks List
|
||||
..._homeworks.map((hw) => Container(
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF0F172A),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: const Color(0xFF1E293B)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(hw['title'], style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w800, color: Colors.white)),
|
||||
const SizedBox(height: 4),
|
||||
Text('${hw['class']} · ${hw['due_date']}', style: const TextStyle(fontSize: 11, color: Color(0xFF94A3B8))),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF10B981).withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(hw['submitted'], style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w700, color: Color(0xFF34D399))),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text('معدل الشعبة: ${hw['average_score']}', style: const TextStyle(fontSize: 10.5, color: Color(0xFF64748B))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
const SizedBox(height: 18),
|
||||
|
||||
// Student Doubts Section
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.bubble_left_bubble_right_fill, color: Color(0xFF38BDF8), size: 18),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'استفسارات وأسئلة الطلبة الميدانية (غرفة الشكوك) 💬',
|
||||
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w800, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
..._studentDoubts.asMap().entries.map((entry) {
|
||||
final idx = entry.key;
|
||||
final d = entry.value;
|
||||
final replied = d['replied'] as bool;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF0F172A),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(
|
||||
color: replied ? const Color(0xFF10B981).withOpacity(0.3) : const Color(0xFF38BDF8).withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('${d['student_name']} · ${d['class']}', style: const TextStyle(fontSize: 12.5, fontWeight: FontWeight.w800, color: Color(0xFF38BDF8))),
|
||||
Text(d['time'], style: const TextStyle(fontSize: 11, color: Color(0xFF64748B))),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
d['question'],
|
||||
style: const TextStyle(fontSize: 13, color: Colors.white, height: 1.4),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (replied)
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.checkmark_seal_fill, color: Color(0xFF34D399), size: 15),
|
||||
SizedBox(width: 6),
|
||||
Text('تم إرسال الرد الصوتي للطالب 🎧', style: TextStyle(fontSize: 11.5, color: Color(0xFF6EE7B7), fontWeight: FontWeight.w700)),
|
||||
],
|
||||
)
|
||||
else
|
||||
const Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.clock_fill, color: Color(0xFFFBBF24), size: 14),
|
||||
SizedBox(width: 6),
|
||||
Text('بانتظار إجابة المعلم', style: TextStyle(fontSize: 11.5, color: Color(0xFFFBBF24))),
|
||||
],
|
||||
),
|
||||
if (!replied)
|
||||
ElevatedButton.icon(
|
||||
onPressed: () => _recordVoiceReply(idx),
|
||||
icon: const Icon(CupertinoIcons.mic_fill, size: 14),
|
||||
label: const Text('تسجيل رد صوتي 🎙️', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w700)),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF0284C7),
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user