- Create auth feature with Clean Architecture (domain/data/presentation) - Add login and register pages with form validation - Implement secure token storage with flutter_secure_storage - Create AuthenticatedClient for automatic Bearer token headers - Add AuthViewModel for global auth state management - Update router with auth guards (redirect to login if not authenticated) - Add logout option to settings page - Update TaskRemoteDataSource to use authenticated client - Add auth-related localization strings (EN/DE)
93 lines
2.7 KiB
Dart
93 lines
2.7 KiB
Dart
import 'package:go_router/go_router.dart';
|
|
|
|
import '../core/di/injection_container.dart';
|
|
import '../features/auth/presentation/pages/login_page.dart';
|
|
import '../features/auth/presentation/pages/register_page.dart';
|
|
import '../features/auth/presentation/viewmodels/auth_viewmodel.dart';
|
|
import '../features/tasks/presentation/pages/daily_agenda_page.dart';
|
|
import '../features/tasks/presentation/pages/calendar_page.dart';
|
|
import '../features/tasks/presentation/pages/task_form_page.dart';
|
|
import '../features/settings/presentation/pages/settings_page.dart';
|
|
|
|
class AppRouter {
|
|
static GoRouter? _router;
|
|
|
|
static GoRouter get router {
|
|
_router ??= _createRouter();
|
|
return _router!;
|
|
}
|
|
|
|
static GoRouter _createRouter() {
|
|
return GoRouter(
|
|
initialLocation: '/',
|
|
redirect: (context, state) {
|
|
final authViewModel = getIt<AuthViewModel>();
|
|
final isAuthenticated = authViewModel.isAuthenticated;
|
|
final isAuthRoute =
|
|
state.matchedLocation == '/login' || state.matchedLocation == '/register';
|
|
|
|
if (authViewModel.state == AuthState.initial) {
|
|
return null;
|
|
}
|
|
|
|
if (!isAuthenticated && !isAuthRoute) {
|
|
return '/login';
|
|
}
|
|
|
|
if (isAuthenticated && isAuthRoute) {
|
|
return '/';
|
|
}
|
|
|
|
return null;
|
|
},
|
|
refreshListenable: getIt<AuthViewModel>(),
|
|
routes: [
|
|
GoRoute(
|
|
path: '/login',
|
|
name: 'login',
|
|
builder: (context, state) => const LoginPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/register',
|
|
name: 'register',
|
|
builder: (context, state) => const RegisterPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/',
|
|
name: 'daily',
|
|
builder: (context, state) {
|
|
final dateStr = state.uri.queryParameters['date'];
|
|
return DailyAgendaPage(initialDate: dateStr);
|
|
},
|
|
),
|
|
GoRoute(
|
|
path: '/calendar',
|
|
name: 'calendar',
|
|
builder: (context, state) => const CalendarPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/task/new',
|
|
name: 'task-new',
|
|
builder: (context, state) {
|
|
final dateStr = state.uri.queryParameters['date'];
|
|
return TaskFormPage(initialDate: dateStr);
|
|
},
|
|
),
|
|
GoRoute(
|
|
path: '/task/:id/edit',
|
|
name: 'task-edit',
|
|
builder: (context, state) {
|
|
final taskId = state.pathParameters['id']!;
|
|
return TaskFormPage(taskId: taskId);
|
|
},
|
|
),
|
|
GoRoute(
|
|
path: '/settings',
|
|
name: 'settings',
|
|
builder: (context, state) => const SettingsPage(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|