feat: add recipe creation, editing, and detail screens; enhance recipe model with instructions and ingredients

This commit is contained in:
Nils-Johan Gynther
2026-04-22 07:53:25 +02:00
parent 2ea18503ef
commit ed4e18dc31
10 changed files with 1017 additions and 44 deletions
+34 -4
View File
@@ -7,6 +7,9 @@ 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) {
@@ -22,22 +25,18 @@ final appRouterProvider = Provider<GoRouter>((ref) {
final isSplash = location == '/';
final isLogin = location == '/login';
// Keep user on splash while auth state is being resolved from storage.
if (isLoading) {
return isSplash ? null : '/';
}
// Redirect away from splash once auth is known.
if (isSplash) {
return isLoggedIn ? '/recipes' : '/login';
}
// Unauthenticated user trying to reach a protected route.
if (!isLoggedIn && !isLogin) {
return '/login';
}
// Authenticated user landing on login.
if (isLoggedIn && isLogin) {
return '/recipes';
}
@@ -55,6 +54,37 @@ final appRouterProvider = Provider<GoRouter>((ref) {
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);