Files
unionflow-mobile-apps/lib/app/router/app_router.dart
dahoud 65b5c79c43 feat(auth): gestion reAuthRequired + suppression flux changement mot de passe manuel
- AuthStatusResult: nouveau champ reAuthRequired (ancien compte nécessitant UPDATE_PASSWORD)
- AuthBloc._onLoginRequested: si reAuthRequired → logout silencieux + re-déclenchement AppAuth
  automatique (Keycloak affiche l'écran de changement de mot de passe dans Chrome Custom Tab)
- AuthBloc._onStatusChecked: si reAuthRequired → logout + AuthUnauthenticated (redirection login)
- Remplacement du flux premierLoginComplet (boolean) par enum côté backend
- Suppression de AuthPasswordChangeRequired, AuthPasswordChanging, change_password_page.dart
2026-04-05 11:13:36 +00:00

112 lines
4.9 KiB
Dart

/// Configuration centralisée des routes de l'application
///
/// Gère toutes les routes et la navigation de l'application UnionFlow
library app_router;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../features/authentication/presentation/bloc/auth_bloc.dart';
import '../../features/authentication/presentation/pages/login_page.dart';
import '../../features/about/presentation/pages/about_page.dart';
import '../../features/help/presentation/pages/help_support_page.dart';
import '../../features/profile/presentation/pages/profile_page_wrapper.dart';
import '../../features/organizations/presentation/pages/organizations_page_wrapper.dart';
import '../../features/members/presentation/pages/members_page_wrapper.dart';
import '../../features/events/presentation/pages/events_page_wrapper.dart';
import '../../features/solidarity/presentation/pages/demandes_aide_page_wrapper.dart';
import '../../features/contributions/presentation/pages/contributions_page_wrapper.dart';
import '../../features/reports/presentation/pages/reports_page_wrapper.dart';
import '../../features/adhesions/presentation/pages/adhesions_page_wrapper.dart';
import '../../features/settings/presentation/pages/system_settings_page.dart';
import '../../features/dashboard/presentation/pages/advanced_dashboard_page.dart';
import '../../features/admin/presentation/pages/user_management_page.dart';
import '../../features/communication/presentation/pages/conversations_page.dart';
import '../../features/finance_workflow/presentation/pages/pending_approvals_page.dart';
import '../../features/finance_workflow/presentation/pages/budgets_list_page.dart';
import '../../core/navigation/main_navigation_layout.dart';
import '../../features/onboarding/presentation/pages/onboarding_flow_page.dart';
/// Configuration des routes de l'application
class AppRouter {
/// Routes principales de l'application
static Map<String, WidgetBuilder> get routes => {
'/': (context) => BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
// Compte bloqué (SUSPENDU / DESACTIVE) → dialog informatif
if (state is AuthAccountNotActive) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (_) => AlertDialog(
icon: const Icon(
Icons.lock_person_outlined,
color: Color(0xFFB71C1C),
size: 48,
),
title: const Text('Accès refusé'),
content: Text(state.message),
actions: [
ElevatedButton(
onPressed: () => Navigator.of(_).pop(),
child: const Text('OK'),
),
],
),
);
}
},
builder: (context, state) {
if (state is AuthLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
} else if (state is AuthAuthenticated) {
return const MainNavigationLayout();
} else if (state is AuthPendingOnboarding) {
// OrgAdmin EN_ATTENTE_VALIDATION → workflow d'onboarding
return OnboardingFlowPage(
onboardingState: state.onboardingState,
organisationId: state.organisationId ?? '',
souscriptionId: state.souscriptionId,
typeOrganisation: state.typeOrganisation,
);
} else {
return const LoginPage();
}
},
),
'/login': (context) => const LoginPage(),
'/about': (context) => const AboutPage(),
'/help': (context) => const HelpSupportPage(),
'/profile': (context) => const ProfilePageWrapper(),
'/organizations': (context) => const OrganizationsPageWrapper(),
'/members': (context) => const MembersPageWrapper(),
'/events': (context) => const EventsPageWrapper(),
'/solidarity': (context) => const DemandesAidePageWrapper(),
'/reports': (context) => const ReportsPageWrapper(),
'/finances': (context) => const CotisationsPageWrapper(),
'/adhesions': (context) => const AdhesionsPageWrapper(),
'/messages': (context) => const ConversationsPage(),
'/settings': (context) => const SystemSettingsPage(),
'/analytics': (context) {
final authState = context.read<AuthBloc>().state;
if (authState is AuthAuthenticated) {
final orgId = authState.user.organizationContexts.isNotEmpty
? authState.user.organizationContexts.first.organizationId
: '';
return AdvancedDashboardPage(
organizationId: orgId,
userId: authState.user.id,
);
}
return const LoginPage();
},
'/global-users': (context) => const UserManagementPage(),
'/approvals': (context) => const PendingApprovalsPage(),
'/budgets': (context) => const BudgetsListPage(),
};
/// Route initiale de l'application
static const String initialRoute = '/';
}