feat(#175,#176): modale générique Ajouter une carte + CTA pilule
Creation absence (parent) et conge/arret (AM) via une seule modale Material, catalogue UI extensible, calendrier de periode compact. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,11 +2,14 @@ import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:p_tits_pas/models/carte_bulle.dart';
|
||||
import 'package:p_tits_pas/models/carte_type_ui.dart';
|
||||
import 'package:p_tits_pas/services/api/api_config.dart';
|
||||
import 'package:p_tits_pas/services/api/tokenService.dart';
|
||||
|
||||
/// Accès API Cartes (file d'attention) — tickets #173 / #194.
|
||||
/// Accès API Cartes (file d'attention) — tickets #173 / #175 / #194.
|
||||
/// - GET /cards?placementId=
|
||||
/// - GET /cards/types
|
||||
/// - POST /cards
|
||||
/// - POST /cards/:id/respond
|
||||
class CardsService {
|
||||
static Future<Map<String, String>> _headers() async {
|
||||
@@ -57,6 +60,60 @@ class CardsService {
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Types SYSTEM émissibles pour le rôle connecté.
|
||||
static Future<List<CarteTypeEmissible>> listerTypes() async {
|
||||
final response = await http.get(
|
||||
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.cards}/types'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception(
|
||||
_extractError(response.body, 'Erreur chargement des types de cartes'),
|
||||
);
|
||||
}
|
||||
final decoded = jsonDecode(response.body);
|
||||
final list = decoded is List
|
||||
? decoded
|
||||
: (decoded is Map ? decoded['items'] as List? : null) ?? const [];
|
||||
return list
|
||||
.whereType<Map>()
|
||||
.map((e) => CarteTypeEmissible.fromJson(Map<String, dynamic>.from(e)))
|
||||
.where((t) => t.code.isNotEmpty)
|
||||
// Modif d’absence = agenda, pas la modale cartes (#175).
|
||||
.where((t) => t.code != 'absence_enfant_modif')
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Créer une bulle (+ événement agenda côté back).
|
||||
static Future<CarteBulle> creer({
|
||||
required String typeCode,
|
||||
required String idPlacement,
|
||||
required String dateDebut,
|
||||
required String dateFin,
|
||||
String? motif,
|
||||
}) async {
|
||||
final response = await http.post(
|
||||
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.cards}'),
|
||||
headers: await _headers(),
|
||||
body: jsonEncode({
|
||||
'type_code': typeCode,
|
||||
'id_placement': idPlacement,
|
||||
'date_debut': dateDebut,
|
||||
'date_fin': dateFin,
|
||||
if (motif != null && motif.trim().isNotEmpty) 'motif': motif.trim(),
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode != 201 && response.statusCode != 200) {
|
||||
throw Exception(
|
||||
_extractError(response.body, 'Erreur lors de la création'),
|
||||
);
|
||||
}
|
||||
|
||||
final decoded = jsonDecode(response.body);
|
||||
return CarteBulle.fromJson(Map<String, dynamic>.from(decoded as Map));
|
||||
}
|
||||
|
||||
/// Répondre : accept | refuse | ack.
|
||||
static Future<CarteBulle> repondre({
|
||||
required String cardId,
|
||||
@@ -75,7 +132,7 @@ class CardsService {
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
if (response.statusCode != 200 && response.statusCode != 201) {
|
||||
throw Exception(
|
||||
_extractError(response.body, 'Erreur lors de la réponse'),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user