105 lines
5.6 KiB
Dart
105 lines
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
import 'auth_provider.dart';
|
|
import '../features/auth/login_screen.dart';
|
|
import '../features/auth/waiting_approval_screen.dart';
|
|
import '../features/splash/splash_screen.dart';
|
|
import '../features/home/home_dashboard.dart';
|
|
import '../features/children/children_list_screen.dart';
|
|
import '../features/children/child_detail_screen.dart';
|
|
import '../features/diary/new_diary_screen.dart';
|
|
import '../features/diary/diary_history_screen.dart';
|
|
import '../features/attendance/attendance_screen.dart';
|
|
import '../features/payments/payments_screen.dart';
|
|
import '../features/announcements/announcements_screen.dart';
|
|
import '../features/chat/chat_list_screen.dart';
|
|
import '../features/chat/chat_screen.dart';
|
|
import '../features/profile/profile_screen.dart';
|
|
import '../features/users/users_management_screen.dart';
|
|
import '../features/settings/settings_screen.dart';
|
|
import '../features/medication/medication_screen.dart';
|
|
import '../features/menu/menu_screen.dart';
|
|
|
|
const _adminRoles = ['principal', 'admin'];
|
|
const _staffRoles = ['principal', 'admin', 'teacher', 'staff'];
|
|
const _allRoles = ['principal', 'admin', 'teacher', 'staff', 'parent'];
|
|
|
|
final goRouterProvider = Provider<GoRouter>((ref) {
|
|
return GoRouter(
|
|
initialLocation: '/splash',
|
|
redirect: (context, state) {
|
|
final session = Supabase.instance.client.auth.currentSession;
|
|
final publicPaths = ['/login', '/splash', '/waiting'];
|
|
final isPublic = publicPaths.any((p) => state.fullPath?.startsWith(p) ?? false);
|
|
if (session == null && !isPublic) return '/login';
|
|
return null;
|
|
},
|
|
routes: [
|
|
GoRoute(path: '/splash', builder: (_, __) => const SplashScreen()),
|
|
GoRoute(path: '/login', builder: (_, __) => const LoginScreen()),
|
|
GoRoute(path: '/waiting', builder: (_, __) => const WaitingApprovalScreen()),
|
|
GoRoute(path: '/home', builder: (_, __) => const HomeDashboard()),
|
|
GoRoute(path: '/profile', builder: (_, __) => const ProfileScreen()),
|
|
|
|
// ── Todos (incluindo encarregados) ─────────────────────
|
|
GoRoute(path: '/chat', builder: (_, __) => const _Guard(roles: _allRoles, child: ChatListScreen())),
|
|
GoRoute(path: '/chat/:userId', builder: (_, state) => _Guard(
|
|
roles: _allRoles, child: ChatScreen(toUserId: state.pathParameters['userId']!))),
|
|
GoRoute(path: '/menu', builder: (_, __) => const _Guard(roles: _allRoles, child: MenuScreen())),
|
|
GoRoute(path: '/medication', builder: (_, __) => const _Guard(roles: _allRoles, child: MedicationScreen())),
|
|
GoRoute(path: '/announcements', builder: (_, __) => const _Guard(roles: _allRoles, child: AnnouncementsScreen())),
|
|
|
|
// ── Staff (educadoras, auxiliares, admins) ─────────────
|
|
GoRoute(path: '/children', builder: (_, __) => const _Guard(roles: _staffRoles, child: ChildrenListScreen())),
|
|
GoRoute(path: '/child/:id', builder: (_, state) => _Guard(
|
|
roles: _staffRoles, child: ChildDetailScreen(id: state.pathParameters['id']!))),
|
|
GoRoute(path: '/new-diary', builder: (_, state) => _Guard(
|
|
roles: _staffRoles, child: NewDiaryScreen(childId: state.uri.queryParameters['childId']))),
|
|
GoRoute(path: '/diary-history/:childId', builder: (_, state) => _Guard(
|
|
roles: _staffRoles, child: DiaryHistoryScreen(childId: state.pathParameters['childId']!))),
|
|
GoRoute(path: '/attendance', builder: (_, __) => const _Guard(roles: _staffRoles, child: AttendanceScreen())),
|
|
|
|
// ── Admin / Principal apenas ───────────────────────────
|
|
GoRoute(path: '/payments', builder: (_, __) => const _Guard(roles: _adminRoles, child: PaymentsScreen())),
|
|
GoRoute(path: '/users', builder: (_, __) => const _Guard(roles: _adminRoles, child: UsersManagementScreen())),
|
|
GoRoute(path: '/settings', builder: (_, __) => const _Guard(roles: _adminRoles, child: SettingsScreen())),
|
|
],
|
|
);
|
|
});
|
|
|
|
class _Guard extends ConsumerWidget {
|
|
final List<String> roles;
|
|
final Widget child;
|
|
const _Guard({required this.roles, required this.child});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final async = ref.watch(currentProfileProvider);
|
|
return async.when(
|
|
data: (profile) {
|
|
if (profile != null && roles.contains(profile.role)) return child;
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFF0D1117),
|
|
body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
const Icon(Icons.lock_outline, color: Color(0xFFE74C3C), size: 64),
|
|
const SizedBox(height: 16),
|
|
const Text('Acesso Não Autorizado',
|
|
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold)),
|
|
const SizedBox(height: 8),
|
|
Text('A tua função não tem permissão para esta área.',
|
|
style: TextStyle(color: Colors.white.withOpacity(0.4), fontSize: 13)),
|
|
const SizedBox(height: 24),
|
|
TextButton(onPressed: () => context.go('/home'),
|
|
child: const Text('← Voltar ao início', style: TextStyle(color: Color(0xFF4FC3F7)))),
|
|
])),
|
|
);
|
|
},
|
|
loading: () => const Scaffold(backgroundColor: Color(0xFF0D1117),
|
|
body: Center(child: CircularProgressIndicator(color: Color(0xFF4FC3F7)))),
|
|
error: (_, __) => const Scaffold(body: Center(child: Text('Erro'))),
|
|
);
|
|
}
|
|
}
|