Files
dahoud 120434aba0 feat(features): refontes adhesions/admin/auth/backup/contributions/dashboard/epargne/events
- 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
2026-04-15 20:26:48 +00:00

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...'),
);
},
),
);
}
}