Navigation
Screen Flow
┌──────────────────┐
│ Splash │
│ (auth + eval │
│ mode check) │
└────────┬─────────┘
│
┌──────────────┴──────────────┐
│ │
┌──────▼──────┐ ┌───────▼───────┐
│ Login │ │ Home │
│ (OTP/PIN) │ │ (Dashboard) │
└──────┬──────┘ └───────┬───────┘
│ │
│ ┌──────────┴──────────┐
│ ┌───────▼──────┐ │
│ │ Bottom Nav │ │
│ │ Home│ Student │ Modules│ Profile│
│ └────────────────────────────┘
│ │
│ Modules (Grid) ──► Feature Screens
│
┌───────▼──────┐
│ Student Leave │
│ (Special tab) │
└───────────────┘
Bottom Navigation
4 tabs:
| Tab | Screens |
|---|---|
| Home | Dashboard, today's schedule |
| Student Leave | Approve/reject student leave requests |
| Messages | Broadcasts, direct messages |
| Modules | Grid of all feature modules |
| Profile | Teacher profile, settings |
AppNavigator
// lib/core/navigation/app_navigator.dart
class AppNavigator {
static const String splash = '/';
static const String login = '/login';
static const String home = '/home';
static const String attendance = '/attendance';
static const String exams = '/exams';
static const String results = '/results';
// ...
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case splash: return MaterialPageRoute(builder: (_) => const SplashScreen());
case login: return MaterialPageRoute(builder: (_) => const LoginScreen());
case home: return MaterialPageRoute(builder: (_) => const HomeScreen());
case attendance: return MaterialPageRoute(builder: (_) => const AttendanceScreen());
// ...
}
}
}
Module Grid
Modules are shown in a grid with write-access indicators:
GridView.count(
crossAxisCount: 3,
children: [
ModuleTile(
icon: Icons.check_circle,
label: 'Attendance',
hasWriteAccess: vm.canWriteAttendance,
isEvaluationMode: vm.isEvaluationMode,
onTap: () => Navigator.pushNamed('/attendance'),
),
ModuleTile(
icon: Icons.assignment,
label: 'Exams',
hasWriteAccess: true, // Always writable
isEvaluationMode: false,
onTap: () => Navigator.pushNamed('/exams'),
),
// ...
],
)