Refactor user and theme management to use BLoC pattern; remove provider classes and integrate new services for user and group functionalities

This commit is contained in:
Dayron
2025-10-14 12:10:42 +02:00
parent c4588a65c0
commit 72ddb58a11
27 changed files with 1864 additions and 791 deletions

View File

@@ -0,0 +1,126 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'user_event.dart' as event;
import 'user_state.dart' as state;
class UserBloc extends Bloc<event.UserEvent, state.UserState> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
UserBloc() : super(state.UserInitial()) {
on<event.UserInitialized>(_onUserInitialized);
on<event.LoadUser>(_onLoadUser);
on<event.UserUpdated>(_onUserUpdated);
on<event.UserLoggedOut>(_onUserLoggedOut);
}
Future<void> _onUserInitialized(
event.UserInitialized event,
Emitter<state.UserState> emit,
) async {
emit(state.UserLoading());
try {
final currentUser = _auth.currentUser;
if (currentUser == null) {
emit(state.UserError('Aucun utilisateur connecté'));
return;
}
// Récupérer les données utilisateur depuis Firestore
final userDoc = await _firestore
.collection('users')
.doc(currentUser.uid)
.get();
if (!userDoc.exists) {
// Créer un utilisateur par défaut si non existant
final defaultUser = state.UserModel(
id: currentUser.uid,
email: currentUser.email ?? '',
prenom: currentUser.displayName ?? 'Voyageur',
);
await _firestore
.collection('users')
.doc(currentUser.uid)
.set(defaultUser.toJson());
emit(state.UserLoaded(defaultUser));
} else {
final user = state.UserModel.fromJson({
'id': currentUser.uid,
...userDoc.data()!,
});
emit(state.UserLoaded(user));
}
} catch (e) {
emit(state.UserError('Erreur lors du chargement de l\'utilisateur: $e'));
}
}
Future<void> _onLoadUser(
event.LoadUser event,
Emitter<state.UserState> emit,
) async {
emit(state.UserLoading());
try {
final userDoc = await _firestore
.collection('users')
.doc(event.userId)
.get();
if (userDoc.exists) {
final user = state.UserModel.fromJson({
'id': event.userId,
...userDoc.data()!,
});
emit(state.UserLoaded(user));
} else {
emit(state.UserError('Utilisateur non trouvé'));
}
} catch (e) {
emit(state.UserError('Erreur lors du chargement: $e'));
}
}
Future<void> _onUserUpdated(
event.UserUpdated event,
Emitter<state.UserState> emit,
) async {
if (this.state is state.UserLoaded) {
final currentUser = (this.state as state.UserLoaded).user;
try {
await _firestore
.collection('users')
.doc(currentUser.id)
.update(event.userData);
final updatedDoc = await _firestore
.collection('users')
.doc(currentUser.id)
.get();
final updatedUser = state.UserModel.fromJson({
'id': currentUser.id,
...updatedDoc.data()!,
});
emit(state.UserLoaded(updatedUser));
} catch (e) {
emit(state.UserError('Erreur lors de la mise à jour: $e'));
}
}
}
Future<void> _onUserLoggedOut(
event.UserLoggedOut event,
Emitter<state.UserState> emit,
) async {
emit(state.UserInitial());
}
}

View File

@@ -0,0 +1,22 @@
abstract class UserEvent {}
class UserInitialized extends UserEvent {}
class UserLoaded extends UserEvent {
final String userId;
UserLoaded(this.userId);
}
class UserUpdated extends UserEvent {
final Map<String, dynamic> userData;
UserUpdated(this.userData);
}
class UserLoggedOut extends UserEvent {}
class LoadUser extends UserEvent {
final String userId;
LoadUser(this.userId);
}

View File

@@ -0,0 +1,61 @@
import 'package:equatable/equatable.dart';
abstract class UserState extends Equatable {
@override
List<Object?> get props => [];
}
class UserInitial extends UserState {}
class UserLoading extends UserState {}
class UserLoaded extends UserState {
final UserModel user;
UserLoaded(this.user);
@override
List<Object?> get props => [user];
}
class UserError extends UserState {
final String message;
UserError(this.message);
@override
List<Object?> get props => [message];
}
// Modèle utilisateur simple
class UserModel {
final String id;
final String email;
final String prenom;
final String? nom;
UserModel({
required this.id,
required this.email,
required this.prenom,
this.nom,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] ?? '',
email: json['email'] ?? '',
prenom: json['prenom'] ?? 'Voyageur',
nom: json['nom'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'email': email,
'prenom': prenom,
'nom': nom,
};
}
}