144 lines
4.2 KiB
Dart
144 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import '../features/auth/presentation/login_screen.dart';
|
|
import '../features/auth/presentation/register_screen.dart';
|
|
import '../features/clients/presentation/clients_screen.dart';
|
|
import '../features/clients/presentation/client_detail_screen.dart';
|
|
import '../features/clients/presentation/client_form_screen.dart';
|
|
import '../features/emails/presentation/emails_screen.dart';
|
|
import '../features/emails/presentation/email_compose_screen.dart';
|
|
import '../features/events/presentation/events_screen.dart';
|
|
import '../shared/providers/auth_provider.dart';
|
|
|
|
final routerProvider = Provider<GoRouter>((ref) {
|
|
final authState = ref.watch(authStateProvider);
|
|
|
|
return GoRouter(
|
|
initialLocation: '/',
|
|
redirect: (context, state) {
|
|
final isLoggedIn = authState.valueOrNull?.isAuthenticated ?? false;
|
|
final isAuthRoute = state.matchedLocation == '/login' ||
|
|
state.matchedLocation == '/register';
|
|
|
|
if (!isLoggedIn && !isAuthRoute) {
|
|
return '/login';
|
|
}
|
|
|
|
if (isLoggedIn && isAuthRoute) {
|
|
return '/';
|
|
}
|
|
|
|
return null;
|
|
},
|
|
routes: [
|
|
// Auth routes
|
|
GoRoute(
|
|
path: '/login',
|
|
builder: (context, state) => const LoginScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/register',
|
|
builder: (context, state) => const RegisterScreen(),
|
|
),
|
|
|
|
// Main app routes
|
|
ShellRoute(
|
|
builder: (context, state, child) => MainShell(child: child),
|
|
routes: [
|
|
GoRoute(
|
|
path: '/',
|
|
builder: (context, state) => const ClientsScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/clients/new',
|
|
builder: (context, state) => const ClientFormScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/clients/:id',
|
|
builder: (context, state) => ClientDetailScreen(
|
|
clientId: state.pathParameters['id']!,
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/clients/:id/edit',
|
|
builder: (context, state) => ClientFormScreen(
|
|
clientId: state.pathParameters['id'],
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/emails',
|
|
builder: (context, state) => const EmailsScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/emails/compose',
|
|
builder: (context, state) => EmailComposeScreen(
|
|
clientId: state.uri.queryParameters['clientId'],
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/events',
|
|
builder: (context, state) => const EventsScreen(),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
});
|
|
|
|
class MainShell extends StatelessWidget {
|
|
final Widget child;
|
|
|
|
const MainShell({super.key, required this.child});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: child,
|
|
bottomNavigationBar: NavigationBar(
|
|
selectedIndex: _getSelectedIndex(context),
|
|
onDestinationSelected: (index) => _onDestinationSelected(context, index),
|
|
destinations: const [
|
|
NavigationDestination(
|
|
icon: Icon(Icons.people_outline),
|
|
selectedIcon: Icon(Icons.people),
|
|
label: 'Clients',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.email_outline),
|
|
selectedIcon: Icon(Icons.email),
|
|
label: 'Emails',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.event_outline),
|
|
selectedIcon: Icon(Icons.event),
|
|
label: 'Events',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
int _getSelectedIndex(BuildContext context) {
|
|
final location = GoRouterState.of(context).matchedLocation;
|
|
if (location.startsWith('/emails')) return 1;
|
|
if (location.startsWith('/events')) return 2;
|
|
return 0;
|
|
}
|
|
|
|
void _onDestinationSelected(BuildContext context, int index) {
|
|
switch (index) {
|
|
case 0:
|
|
context.go('/');
|
|
break;
|
|
case 1:
|
|
context.go('/emails');
|
|
break;
|
|
case 2:
|
|
context.go('/events');
|
|
break;
|
|
}
|
|
}
|
|
}
|