class AuthenticatedProfile { const AuthenticatedProfile({ required this.id, required this.nom, required this.prenom, required this.email, required this.classe, required this.roleCode, required this.roleLabel, required this.campusId, required this.campusNom, required this.campusVille, }); final int id; final String nom; final String prenom; final String email; final String? classe; final String roleCode; final String roleLabel; final int campusId; final String campusNom; final String campusVille; factory AuthenticatedProfile.fromApi(dynamic reponse) { if (reponse is! Map || reponse["data"] is! Map) { throw const FormatException("Profil utilisateur invalide."); } final data = reponse["data"] as Map; final role = data["role"]; final campus = data["campus"]; if (role is! Map || campus is! Map) { throw const FormatException("Role ou campus utilisateur invalide."); } final id = data["id"]; final campusId = campus["id"]; if (id is! int || campusId is! int) { throw const FormatException("Identifiant utilisateur invalide."); } final classe = data["classe"]; if (classe != null && classe is! String) { throw const FormatException("Classe utilisateur invalide."); } return AuthenticatedProfile( id: id, nom: _requiredString(data, "nom"), prenom: _requiredString(data, "prenom"), email: _requiredString(data, "email"), classe: classe as String?, roleCode: _requiredString(role, "code"), roleLabel: _requiredString(role, "libelle"), campusId: campusId, campusNom: _requiredString(campus, "nom"), campusVille: _requiredString(campus, "ville"), ); } String get fullName => "$prenom $nom"; String get initials { final first = prenom.trim().isEmpty ? "" : prenom.trim()[0]; final last = nom.trim().isEmpty ? "" : nom.trim()[0]; return "$first$last".toUpperCase(); } String get campusTag => "$campusNom · $campusVille"; String get subtitle { final details = [roleLabel]; final studentClass = classe?.trim(); if (studentClass != null && studentClass.isNotEmpty) { details.add(studentClass); } details.add(campusTag); return details.join(" · "); } static String _requiredString(Map source, String key) { final value = source[key]; if (value is! String || value.trim().isEmpty) { throw FormatException("Champ utilisateur invalide : $key."); } return value.trim(); } }