feat: Livraison version 3.0.6

- Amélioration de la gestion des entités et des utilisateurs
- Mise à jour des modèles Amicale et Client avec champs supplémentaires
- Ajout du service de logging et amélioration du chargement UI
- Refactoring des formulaires utilisateur et amicale
- Intégration de file_picker et image_picker pour la gestion des fichiers
- Amélioration de la gestion des membres et de leur suppression
- Optimisation des performances de l'API
- Mise à jour de la documentation technique

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-08 20:33:54 +02:00
parent 1018b86537
commit 0e98a94374
63 changed files with 104136 additions and 87983 deletions

View File

@@ -18,6 +18,10 @@ class ApiService {
late final String _baseUrl;
late final String _appIdentifier;
String? _sessionId;
// Getters pour les propriétés (lecture seule)
String? get sessionId => _sessionId;
String get baseUrl => _baseUrl;
// Singleton thread-safe
static ApiService get instance {
@@ -142,8 +146,11 @@ class ApiService {
Future<Response> post(String path, {dynamic data}) async {
try {
return await _dio.post(path, data: data);
} on DioException catch (e) {
throw ApiException.fromDioException(e);
} catch (e) {
rethrow;
if (e is ApiException) rethrow;
throw ApiException('Erreur inattendue lors de la requête POST', originalError: e);
}
}
@@ -151,8 +158,11 @@ class ApiService {
Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) async {
try {
return await _dio.get(path, queryParameters: queryParameters);
} on DioException catch (e) {
throw ApiException.fromDioException(e);
} catch (e) {
rethrow;
if (e is ApiException) rethrow;
throw ApiException('Erreur inattendue lors de la requête GET', originalError: e);
}
}
@@ -160,8 +170,11 @@ class ApiService {
Future<Response> put(String path, {dynamic data}) async {
try {
return await _dio.put(path, data: data);
} on DioException catch (e) {
throw ApiException.fromDioException(e);
} catch (e) {
rethrow;
if (e is ApiException) rethrow;
throw ApiException('Erreur inattendue lors de la requête PUT', originalError: e);
}
}
@@ -169,8 +182,81 @@ class ApiService {
Future<Response> delete(String path) async {
try {
return await _dio.delete(path);
} on DioException catch (e) {
throw ApiException.fromDioException(e);
} catch (e) {
rethrow;
if (e is ApiException) rethrow;
throw ApiException('Erreur inattendue lors de la requête DELETE', originalError: e);
}
}
// Méthode pour uploader un logo d'amicale
Future<Map<String, dynamic>> uploadLogo(int entiteId, dynamic imageFile) async {
try {
FormData formData;
// Gestion différente selon la plateforme (Web ou Mobile)
if (kIsWeb) {
// Pour le web, imageFile est un XFile
final bytes = await imageFile.readAsBytes();
// Vérification de la taille (5 Mo max)
const int maxSize = 5 * 1024 * 1024;
if (bytes.length > maxSize) {
throw ApiException(
'Le fichier est trop volumineux. Taille maximale: 5 Mo',
statusCode: 413
);
}
formData = FormData.fromMap({
'logo': MultipartFile.fromBytes(
bytes,
filename: imageFile.name,
),
});
} else {
// Pour mobile, imageFile est un File
final fileLength = await imageFile.length();
// Vérification de la taille (5 Mo max)
const int maxSize = 5 * 1024 * 1024;
if (fileLength > maxSize) {
throw ApiException(
'Le fichier est trop volumineux. Taille maximale: 5 Mo',
statusCode: 413
);
}
formData = FormData.fromMap({
'logo': await MultipartFile.fromFile(
imageFile.path,
filename: imageFile.path.split('/').last,
),
});
}
final response = await _dio.post(
'/entites/$entiteId/logo',
data: formData,
options: Options(
headers: {
'Content-Type': 'multipart/form-data',
},
),
);
if (response.statusCode == 200 || response.statusCode == 201) {
return response.data;
} else {
throw ApiException('Erreur lors de l\'upload du logo',
statusCode: response.statusCode);
}
} on DioException catch (e) {
throw ApiException.fromDioException(e);
} catch (e) {
if (e is ApiException) rethrow;
throw ApiException('Erreur inattendue lors de l\'upload du logo', originalError: e);
}
}