State Management
ViewModel Registry
All ViewModels registered in service_locator.dart:
Future<void> setupServiceLocator() async {
// Auth
getIt.registerFactory<AuthViewModel>(() => AuthViewModel(getIt<AuthService>()));
// Core
getIt.registerFactory<HomeViewModel>(() => HomeViewModel());
getIt.registerFactory<AttendanceViewModel>(() => AttendanceViewModel(getIt<AttendanceService>()));
getIt.registerFactory<ExamViewModel>(() => ExamViewModel(getIt<ExamService>()));
getIt.registerFactory<ResultViewModel>(() => ResultViewModel(getIt<ResultService>()));
getIt.registerFactory<AssignmentViewModel>(() => AssignmentViewModel(getIt<AssignmentService>()));
getIt.registerFactory<LeaveViewModel>(() => LeaveViewModel(getIt<LeaveService>()));
getIt.registerFactory<EventViewModel>(() => EventViewModel(getIt<EventService>()));
getIt.registerFactory<AnnouncementViewModel>(() => AnnouncementViewModel(getIt<AnnouncementService>()));
getIt.registerFactory<SubjectViewModel>(() => SubjectViewModel(getIt<SubjectService>()));
getIt.registerFactory<TimetableViewModel>(() => TimetableViewModel(getIt<TimetableService>()));
getIt.registerFactory<StudentViewModel>(() => StudentViewModel(getIt<StudentService>()));
getIt.registerFactory<CompetitionViewModel>(() => CompetitionViewModel(getIt<CompetitionService>()));
getIt.registerFactory<MessageViewModel>(() => MessageViewModel(getIt<MessageService>()));
getIt.registerFactory<NotificationViewModel>(() => NotificationViewModel(getIt<NotificationService>()));
}
Using ViewModels in Screens
class AttendanceScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<AttendanceViewModel>(
builder: (context, vm, _) {
if (vm.isLoading) return const CircularProgressIndicator();
if (vm.hasError) return ErrorView(message: vm.errorMessage!);
// Check evaluation mode before showing write UI
final authVM = context.watch<AuthViewModel>();
final canWrite = authVM.canWrite('attendance');
return Column(
children: [
if (!canWrite)
Container(
color: Colors.orange.shade100,
padding: const EdgeInsets.all(8),
child: const Text('Read-only — Evaluation Mode is active'),
),
Expanded(child: AttendanceList(records: vm.records)),
if (canWrite) MarkAttendanceFAB(onPressed: vm.markAttendance),
],
);
},
);
}
}
Evaluation Mode Guard in ViewModels
class AttendanceViewModel extends BaseProvider {
Future<void> markAttendance(String studentId, String status) async {
if (isEvaluationMode) {
setError('Attendance cannot be marked during evaluation period');
return;
}
await requestHandler(() async {
await _service.updateAttendance(studentId, status);
});
notifyListeners();
}
bool get isEvaluationMode => _authService.isEvaluationMode;
}