- adhesions : bloc complet avec events/states/model, dialogs paiement/rejet - admin : users bloc, user management list/detail pages - authentication : bloc + keycloak auth service + webview - backup : bloc complet, repository, models - contributions : bloc + widgets + export - dashboard : widgets connectés (activities, events, notifications, search) + charts + monitoring + shortcuts - epargne : repository, transactions, dialogs - events : bloc complet, pages (detail, connected, wrapper), models
163 lines
5.3 KiB
Dart
163 lines
5.3 KiB
Dart
/// Wrapper BLoC pour la page des événements
|
|
///
|
|
/// Ce fichier enveloppe la EventsPage existante avec le EvenementsBloc
|
|
/// pour connecter l'UI riche existante à l'API backend réelle.
|
|
library events_page_wrapper;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
import '../../../../shared/design_system/tokens/color_tokens.dart';
|
|
import '../../../../shared/widgets/error_widget.dart';
|
|
import '../../../../shared/widgets/loading_widget.dart';
|
|
import '../../../../core/utils/logger.dart';
|
|
import '../../bloc/evenements_bloc.dart';
|
|
import '../../bloc/evenements_event.dart';
|
|
import '../../bloc/evenements_state.dart';
|
|
import '../widgets/create_event_dialog.dart';
|
|
import 'events_page_connected.dart';
|
|
|
|
final _getIt = GetIt.instance;
|
|
|
|
/// Wrapper qui fournit le BLoC à la page des événements
|
|
class EventsPageWrapper extends StatelessWidget {
|
|
const EventsPageWrapper({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
AppLogger.info('EventsPageWrapper: Création du BlocProvider');
|
|
|
|
return BlocProvider<EvenementsBloc>(
|
|
create: (context) {
|
|
AppLogger.info('EventsPageWrapper: Initialisation du EvenementsBloc');
|
|
final bloc = _getIt<EvenementsBloc>();
|
|
// Charger les événements au démarrage
|
|
bloc.add(const LoadEvenements());
|
|
return bloc;
|
|
},
|
|
child: const EventsPageConnected(),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Page des événements connectée au BLoC
|
|
///
|
|
/// Cette page gère les états du BLoC et affiche l'UI appropriée
|
|
class EventsPageConnected extends StatelessWidget {
|
|
const EventsPageConnected({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return BlocListener<EvenementsBloc, EvenementsState>(
|
|
listener: (context, state) {
|
|
if (state is EvenementCreated) {
|
|
context.read<EvenementsBloc>().add(const LoadEvenements(refresh: true));
|
|
}
|
|
if (state is EvenementsError) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text(state.message),
|
|
backgroundColor: ColorTokens.error,
|
|
duration: const Duration(seconds: 4),
|
|
action: SnackBarAction(
|
|
label: 'Réessayer',
|
|
textColor: Colors.white,
|
|
onPressed: () {
|
|
context.read<EvenementsBloc>().add(const LoadEvenements());
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
},
|
|
child: BlocBuilder<EvenementsBloc, EvenementsState>(
|
|
builder: (context, state) {
|
|
AppLogger.blocState('EvenementsBloc', state.runtimeType.toString());
|
|
|
|
// État initial
|
|
if (state is EvenementsInitial) {
|
|
return const Center(
|
|
child: AppLoadingWidget(message: 'Initialisation...'),
|
|
);
|
|
}
|
|
|
|
// État de chargement
|
|
if (state is EvenementsLoading) {
|
|
return const Center(
|
|
child: AppLoadingWidget(message: 'Chargement des événements...'),
|
|
);
|
|
}
|
|
|
|
// État de rafraîchissement
|
|
if (state is EvenementsRefreshing) {
|
|
return const Center(
|
|
child: AppLoadingWidget(message: 'Actualisation...'),
|
|
);
|
|
}
|
|
|
|
if (state is EvenementCreated) {
|
|
return const Center(
|
|
child: AppLoadingWidget(message: 'Actualisation...'),
|
|
);
|
|
}
|
|
|
|
if (state is EvenementsLoaded) {
|
|
final evenements = state.evenements;
|
|
AppLogger.info('EventsPageConnected: ${evenements.length} événements chargés');
|
|
|
|
return EventsPageWithData(
|
|
events: evenements,
|
|
totalCount: state.total,
|
|
currentPage: state.page,
|
|
totalPages: state.totalPages,
|
|
onSearch: (query) {
|
|
context.read<EvenementsBloc>().add(LoadEvenements(page: 0, recherche: query));
|
|
},
|
|
onAddEvent: () async {
|
|
await showDialog<void>(
|
|
context: context,
|
|
builder: (_) => const CreateEventDialog(),
|
|
);
|
|
},
|
|
onPageChanged: (page, recherche) {
|
|
context.read<EvenementsBloc>().add(LoadEvenements(page: page, recherche: recherche));
|
|
},
|
|
);
|
|
}
|
|
|
|
// État d'erreur réseau
|
|
if (state is EvenementsNetworkError) {
|
|
AppLogger.error('EventsPageConnected: Erreur réseau', error: state.message);
|
|
return NetworkErrorWidget(
|
|
onRetry: () {
|
|
AppLogger.userAction('Retry load evenements after network error');
|
|
context.read<EvenementsBloc>().add(const LoadEvenements());
|
|
},
|
|
);
|
|
}
|
|
|
|
// État d'erreur générale
|
|
if (state is EvenementsError) {
|
|
AppLogger.error('EventsPageConnected: Erreur', error: state.message);
|
|
return AppErrorWidget(
|
|
message: state.message,
|
|
onRetry: () {
|
|
AppLogger.userAction('Retry load evenements after error');
|
|
context.read<EvenementsBloc>().add(const LoadEvenements());
|
|
},
|
|
);
|
|
}
|
|
|
|
// État par défaut
|
|
AppLogger.warning('EventsPageConnected: État non géré: ${state.runtimeType}');
|
|
return const Center(
|
|
child: AppLoadingWidget(message: 'Chargement...'),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|