Skip to main content

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:

TabScreens
HomeDashboard, today's schedule
Student LeaveApprove/reject student leave requests
MessagesBroadcasts, direct messages
ModulesGrid of all feature modules
ProfileTeacher 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'),
),
// ...
],
)