106 lines
3.4 KiB
Dart
106 lines
3.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import '../ui/app_shell.dart';
|
|
import '../ui/async_state_views.dart';
|
|
import '../../features/auth/data/auth_providers.dart';
|
|
import '../../features/auth/presentation/login_screen.dart';
|
|
import '../../features/profile/presentation/profile_screen.dart';
|
|
import '../../features/recipes/presentation/create_recipe_screen.dart';
|
|
import '../../features/recipes/presentation/recipe_detail_screen.dart';
|
|
import '../../features/recipes/presentation/recipe_edit_screen.dart';
|
|
import '../../features/recipes/presentation/recipes_screen.dart';
|
|
|
|
final appRouterProvider = Provider<GoRouter>((ref) {
|
|
final authState = ref.watch(authStateProvider);
|
|
|
|
return GoRouter(
|
|
initialLocation: '/',
|
|
redirect: (context, state) {
|
|
final isLoading = authState.isLoading;
|
|
final token = authState.valueOrNull;
|
|
final isLoggedIn = token != null && token.isNotEmpty;
|
|
final location = state.matchedLocation;
|
|
final isSplash = location == '/';
|
|
final isLogin = location == '/login';
|
|
|
|
if (isLoading) {
|
|
return isSplash ? null : '/';
|
|
}
|
|
|
|
if (isSplash) {
|
|
return isLoggedIn ? '/recipes' : '/login';
|
|
}
|
|
|
|
if (!isLoggedIn && !isLogin) {
|
|
return '/login';
|
|
}
|
|
|
|
if (isLoggedIn && isLogin) {
|
|
return '/recipes';
|
|
}
|
|
|
|
return null;
|
|
},
|
|
routes: [
|
|
GoRoute(
|
|
path: '/',
|
|
builder: (context, state) => const Scaffold(
|
|
body: LoadingStateView(label: 'Startar...'),
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/login',
|
|
builder: (context, state) => const LoginScreen(),
|
|
),
|
|
// Detail routes — outside ShellRoute to get full-screen with back button.
|
|
// /recipes/create must be listed before /recipes/:id to avoid conflict.
|
|
GoRoute(
|
|
path: '/recipes/create',
|
|
builder: (context, state) => const CreateRecipeScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/recipes/:id',
|
|
redirect: (context, state) {
|
|
final raw = state.pathParameters['id'] ?? '';
|
|
if (int.tryParse(raw) == null) return '/recipes';
|
|
return null;
|
|
},
|
|
builder: (context, state) {
|
|
final id = int.parse(state.pathParameters['id']!);
|
|
return RecipeDetailScreen(recipeId: id);
|
|
},
|
|
),
|
|
GoRoute(
|
|
path: '/recipes/:id/edit',
|
|
redirect: (context, state) {
|
|
final raw = state.pathParameters['id'] ?? '';
|
|
if (int.tryParse(raw) == null) return '/recipes';
|
|
return null;
|
|
},
|
|
builder: (context, state) {
|
|
final id = int.parse(state.pathParameters['id']!);
|
|
return RecipeEditScreen(recipeId: id);
|
|
},
|
|
),
|
|
// Shell routes — shared AppShell with navigation bar.
|
|
ShellRoute(
|
|
builder: (context, state, child) {
|
|
return AppShell(location: state.uri.path, child: child);
|
|
},
|
|
routes: [
|
|
GoRoute(
|
|
path: '/recipes',
|
|
builder: (context, state) => const RecipesScreen(),
|
|
),
|
|
GoRoute(
|
|
path: '/profile',
|
|
builder: (context, state) => const ProfileScreen(),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
});
|