Files
focusflow/lib/routing/app_router.dart
Oracle Public Cloud User 50931d839d Initial scaffold: FocusFlow ADHD Task Manager Flutter app
BLoC/Cubit state management, ADHD-friendly theme (calming teal, no red),
GetIt DI, GoRouter navigation. Screens: task dashboard, focus mode,
task create/detail, streaks, time perception, settings, onboarding, auth.
Custom widgets: TaskCard, RewardPopup, StreakRing, GentleNudgeCard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:53:58 +00:00

124 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../core/network/interceptors/auth_interceptor.dart';
import '../features/auth/presentation/screens/login_screen.dart';
import '../features/auth/presentation/screens/signup_screen.dart';
import '../features/body_doubling/presentation/screens/rooms_screen.dart';
import '../features/settings/presentation/screens/settings_screen.dart';
import '../features/streaks/presentation/screens/streaks_screen.dart';
import '../features/tasks/presentation/screens/create_task_screen.dart';
import '../features/tasks/presentation/screens/focus_mode_screen.dart';
import '../features/tasks/presentation/screens/onboarding_screen.dart';
import '../features/tasks/presentation/screens/task_dashboard_screen.dart';
import '../features/tasks/presentation/screens/task_detail_screen.dart';
import '../features/time_perception/presentation/screens/time_dashboard_screen.dart';
/// Application router using GoRouter.
///
/// Auth redirect: unauthenticated users are sent to /login except
/// when they are already on /login, /signup, or /onboarding.
class AppRouter {
AppRouter._();
static final _rootNavigatorKey = GlobalKey<NavigatorState>();
static final GoRouter router = GoRouter(
navigatorKey: _rootNavigatorKey,
initialLocation: '/',
redirect: _authRedirect,
routes: [
// ── Home / Task Dashboard ────────────────────────────────────
GoRoute(
path: '/',
name: 'home',
builder: (context, state) => const TaskDashboardScreen(),
),
// ── Focus mode — "just do the next thing" ───────────────────
GoRoute(
path: '/focus',
name: 'focus',
builder: (context, state) => const FocusModeScreen(),
),
// ── Auth ─────────────────────────────────────────────────────
GoRoute(
path: '/login',
name: 'login',
builder: (context, state) => const LoginScreen(),
),
GoRoute(
path: '/signup',
name: 'signup',
builder: (context, state) => const SignupScreen(),
),
// ── Task detail ──────────────────────────────────────────────
GoRoute(
path: '/task/:id',
name: 'taskDetail',
builder: (context, state) => TaskDetailScreen(
taskId: state.pathParameters['id']!,
),
),
// ── Create task ──────────────────────────────────────────────
GoRoute(
path: '/task-create',
name: 'createTask',
builder: (context, state) => const CreateTaskScreen(),
),
// ── Streaks ──────────────────────────────────────────────────
GoRoute(
path: '/streaks',
name: 'streaks',
builder: (context, state) => const StreaksScreen(),
),
// ── Time perception ──────────────────────────────────────────
GoRoute(
path: '/time',
name: 'time',
builder: (context, state) => const TimeDashboardScreen(),
),
// ── Body doubling rooms ──────────────────────────────────────
GoRoute(
path: '/rooms',
name: 'rooms',
builder: (context, state) => const RoomsScreen(),
),
// ── Settings ─────────────────────────────────────────────────
GoRoute(
path: '/settings',
name: 'settings',
builder: (context, state) => const SettingsScreen(),
),
// ── Onboarding ───────────────────────────────────────────────
GoRoute(
path: '/onboarding',
name: 'onboarding',
builder: (context, state) => const OnboardingScreen(),
),
],
);
/// Redirect unauthenticated users to /login.
static Future<String?> _authRedirect(
BuildContext context,
GoRouterState state,
) async {
final publicPaths = {'/login', '/signup', '/onboarding'};
if (publicPaths.contains(state.matchedLocation)) return null;
final loggedIn = await AuthInterceptor.hasToken();
if (!loggedIn) return '/login';
return null; // no redirect needed
}
}