import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/theme/app_theme.dart'; import '../../models/exam.dart'; import '../../providers/exam_provider.dart'; class ExamsScreen extends ConsumerWidget { const ExamsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final examsAsync = ref.watch(examProvider); return Scaffold( appBar: AppBar( title: const Text('Exams & Assessments'), ), body: RefreshIndicator( onRefresh: () async { ref.invalidate(examProvider); await ref.read(examProvider.future); }, child: examsAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (err, _) => Center( child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error_outline_rounded, size: 48, color: AppTheme.errorColor), const SizedBox(height: 12), const Text('Failed to load exams', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), const SizedBox(height: 8), Text(err.toString(), textAlign: TextAlign.center, style: const TextStyle(color: AppTheme.textSecondary, fontSize: 13)), const SizedBox(height: 16), ElevatedButton( onPressed: () => ref.refresh(examProvider), child: const Text('Retry'), ), ], ), ), ), data: (exams) { if (exams.isEmpty) { return const Center( child: Padding( padding: EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.quiz_outlined, size: 60, color: AppTheme.textMuted), SizedBox(height: 12), Text( 'No upcoming exams', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600), ), SizedBox(height: 6), Text( 'There are no examinations scheduled at this time.', textAlign: TextAlign.center, style: TextStyle(color: AppTheme.textSecondary, fontSize: 13), ), ], ), ), ); } return ListView.separated( padding: const EdgeInsets.all(16), itemCount: exams.length, separatorBuilder: (_, __) => const SizedBox(height: 10), itemBuilder: (context, index) => _buildExamCard(exams[index]), ); }, ), ), ); } Widget _buildExamCard(Exam exam) { Color badgeBg; Color badgeFg; switch (exam.state.toLowerCase()) { case 'ongoing': badgeBg = AppTheme.warningColor.withOpacity(0.12); badgeFg = AppTheme.warningColor; break; case 'completed': badgeBg = AppTheme.successColor.withOpacity(0.12); badgeFg = AppTheme.successColor; break; case 'scheduled': default: badgeBg = Colors.blue.withOpacity(0.12); badgeFg = Colors.blue.shade700; break; } return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( exam.name, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: AppTheme.textPrimary, ), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: badgeBg, borderRadius: BorderRadius.circular(6), ), child: Text( exam.state.toUpperCase(), style: TextStyle( fontSize: 11, fontWeight: FontWeight.bold, color: badgeFg, ), ), ), ], ), const SizedBox(height: 12), if (exam.startDate != null) Row( children: [ const Icon(Icons.event_note, size: 16, color: AppTheme.textSecondary), const SizedBox(width: 6), Text( 'Start Date: ${exam.startDate!}${exam.endDate != null ? ' - ${exam.endDate!}' : ''}', style: const TextStyle(fontSize: 13, color: AppTheme.textSecondary), ), ], ), if (exam.program?.name != null) ...[ const SizedBox(height: 6), Row( children: [ const Icon(Icons.school, size: 16, color: AppTheme.textSecondary), const SizedBox(width: 6), Text( exam.program!.name, style: const TextStyle(fontSize: 13, color: AppTheme.textSecondary), ), ], ), ], ], ), ), ); } }