feat(materiel): connect catalogue and detail to api

This commit is contained in:
SaidSoighiri94
2026-07-07 13:07:47 +02:00
parent 90d5a65f29
commit 9564dd1ade
15 changed files with 368 additions and 101 deletions
+54
View File
@@ -0,0 +1,54 @@
import "dart:convert";
import "package:http/http.dart" as http;
/// Erreur levée par le client API (serveur injoignable ou réponse en échec).
class ApiException implements Exception {
const ApiException(this.message);
final String message;
@override
String toString() => message;
}
/// Point d'accès unique au backend : centralise l'URL de base, l'en-tête
/// d'authentification (simulée) et la gestion des erreurs.
class ApiClient {
ApiClient._();
static const String _baseUrl = "http://localhost:3000/api";
static const String _utilisateurEmail = "lucas.martin@ensitech.eu";
static Future<dynamic> get(String chemin) async {
final uri = Uri.parse("$_baseUrl$chemin");
late final http.Response reponse;
try {
reponse = await http.get(uri, headers: const {"x-user-email": _utilisateurEmail});
} catch (_) {
throw const ApiException(
"Impossible de joindre le serveur. Vérifiez que le backend est démarré.",
);
}
if (reponse.statusCode >= 200 && reponse.statusCode < 300) {
return jsonDecode(reponse.body);
}
throw ApiException(_messageErreur(reponse));
}
static String _messageErreur(http.Response reponse) {
try {
final corps = jsonDecode(reponse.body);
if (corps is Map && corps["error"] is Map) {
final message = (corps["error"] as Map)["message"];
if (message is String) {
return message;
}
}
} catch (_) {
// Corps non-JSON : on retombe sur le code HTTP.
}
return "Erreur ${reponse.statusCode}";
}
}
@@ -0,0 +1,21 @@
import "../models/materiel_item.dart";
import "api_client.dart";
/// Appels liés au catalogue matériel.
class MaterielService {
MaterielService._();
/// Récupère le catalogue (matériels disponibles du campus de l'utilisateur).
static Future<List<MaterielItem>> getCatalogue() async {
final reponse = await ApiClient.get("/materiels");
final data = (reponse as Map<String, dynamic>)["data"] as List<dynamic>;
return data.map((json) => MaterielItem.fromJson(json as Map<String, dynamic>)).toList();
}
/// Récupère le détail d'un matériel, notamment les accessoires du kit.
static Future<MaterielItem> getDetail(int id) async {
final reponse = await ApiClient.get("/materiels/$id");
final data = (reponse as Map<String, dynamic>)["data"] as Map<String, dynamic>;
return MaterielItem.fromJson(data);
}
}