feat(#207): polish affichage bulles soin + icônes sous-types
Layout type congés (date/heure puis détail italique), assets flacon/pansement/thermo_verre. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 202 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 217 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
@@ -110,11 +110,56 @@ class CarteBulle {
|
|||||||
String? get dateDebut => payload['date_debut']?.toString();
|
String? get dateDebut => payload['date_debut']?.toString();
|
||||||
String? get dateFin => payload['date_fin']?.toString();
|
String? get dateFin => payload['date_fin']?.toString();
|
||||||
String? get motif => payload['motif']?.toString();
|
String? get motif => payload['motif']?.toString();
|
||||||
|
|
||||||
/// Helper pour extraire les informations de soin
|
/// Heure de relevé (payload soins), format API `HH:mm`.
|
||||||
String? get resumerSoin {
|
String? get heureReleve => payload['heure_releve']?.toString();
|
||||||
|
|
||||||
|
/// Heure affichable `18h19` (depuis `heure_releve`).
|
||||||
|
String? get heureReleveAffichee {
|
||||||
|
final h = heureReleve?.trim();
|
||||||
|
if (h == null || h.isEmpty) return null;
|
||||||
|
final parts = h.split(':');
|
||||||
|
if (parts.length < 2) return h;
|
||||||
|
return '${parts[0]}h${parts[1]}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ligne détail soin (sans date/heure) — sous la ligne agenda.
|
||||||
|
String? get detailSoin {
|
||||||
if (!isSoinEnfant) return null;
|
if (!isSoinEnfant) return null;
|
||||||
return payload['motif']?.toString();
|
final st = payload['sous_type']?.toString();
|
||||||
|
if (st == 'fievre') {
|
||||||
|
final t = payload['temperature_c'];
|
||||||
|
final med = payload['medicament_donne']?.toString().trim();
|
||||||
|
String? temp;
|
||||||
|
if (t is num) {
|
||||||
|
temp = t.toStringAsFixed(1).replaceAll('.', ',');
|
||||||
|
} else if (t != null) {
|
||||||
|
temp = t.toString().replaceAll('.', ',');
|
||||||
|
}
|
||||||
|
if (temp == null || temp.isEmpty) return motif;
|
||||||
|
var s = '$temp °C';
|
||||||
|
if (med != null && med.isNotEmpty) {
|
||||||
|
s += ' (Médicament : $med)';
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
if (st == 'bobo') {
|
||||||
|
final nature = payload['bobo_nature']?.toString() ?? 'bobo';
|
||||||
|
final desc = payload['description']?.toString().trim();
|
||||||
|
if (desc != null && desc.isNotEmpty) {
|
||||||
|
return 'Bobo ($nature) : $desc';
|
||||||
|
}
|
||||||
|
return 'Bobo ($nature)';
|
||||||
|
}
|
||||||
|
if (st == 'medicament') {
|
||||||
|
final nom = payload['medicament_nom']?.toString().trim();
|
||||||
|
final ctx = payload['contexte']?.toString().trim();
|
||||||
|
final label =
|
||||||
|
(nom != null && nom.isNotEmpty) ? 'Médicament ($nom)' : 'Médicament';
|
||||||
|
if (ctx != null && ctx.isNotEmpty) return '$label : $ctx';
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
return motif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Motif de refus : réponse API, sinon motif payload (co-parent / reload).
|
/// Motif de refus : réponse API, sinon motif payload (co-parent / reload).
|
||||||
@@ -174,9 +219,9 @@ class CarteBulle {
|
|||||||
return 'assets/images/sac_lapin.png';
|
return 'assets/images/sac_lapin.png';
|
||||||
case 'soin_enfant':
|
case 'soin_enfant':
|
||||||
final st = payload['sous_type']?.toString();
|
final st = payload['sous_type']?.toString();
|
||||||
if (st == 'fievre') return 'assets/images/thermo_croix.png';
|
if (st == 'fievre') return 'assets/images/thermo_verre.png';
|
||||||
if (st == 'medicament') return 'assets/images/cuillere.png'; // Using generic fallback or specific if added later. Assuming thermo_croix or similar could work.
|
if (st == 'bobo') return 'assets/images/pansement.png';
|
||||||
if (st == 'bobo') return 'assets/images/sac_lapin.png'; // Will adjust these later if better assets exist. Let's use generic ones for now, or null if no appropriate assets.
|
if (st == 'medicament') return 'assets/images/flacon.png';
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -612,12 +612,15 @@ class _BulleTile extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _fmtPeriodeUneLigne() {
|
String _fmtPeriodeUneLigne() {
|
||||||
// Si c'est un soin_enfant en singleDay, on affiche juste "Le ..." ou un résumé si pertinent
|
// Soin : « Le 08 octobre 2026 à 18h19 » (détail en italique sous la ligne).
|
||||||
if (card.isSoinEnfant) {
|
if (card.isSoinEnfant) {
|
||||||
final resume = card.resumerSoin;
|
final jour = card.dateDebut != null
|
||||||
final jour = card.dateDebut != null ? 'Le ${_fmtLong(card.dateDebut)}' : '';
|
? 'Le ${_fmtLong(card.dateDebut)}'
|
||||||
if (resume != null) return '$jour\n$resume';
|
: '';
|
||||||
return jour;
|
final h = card.heureReleveAffichee;
|
||||||
|
if (jour.isEmpty) return h != null ? 'À $h' : '';
|
||||||
|
if (h == null || h.isEmpty) return jour;
|
||||||
|
return '$jour à $h';
|
||||||
}
|
}
|
||||||
|
|
||||||
final d1 = DateTime.tryParse(card.dateDebut ?? '');
|
final d1 = DateTime.tryParse(card.dateDebut ?? '');
|
||||||
@@ -723,8 +726,6 @@ class _BulleTile extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
periode,
|
periode,
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: GoogleFonts.merienda(
|
style: GoogleFonts.merienda(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -736,14 +737,27 @@ class _BulleTile extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
if (card.isSoinEnfant &&
|
||||||
|
(card.detailSoin?.trim().isNotEmpty ?? false)) ...[
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
card.detailSoin!,
|
||||||
|
softWrap: true,
|
||||||
|
style: GoogleFonts.merriweather(
|
||||||
|
fontSize: 13,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
height: 1.35,
|
||||||
|
color: encre.ink,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
if (card.isCongeAm &&
|
if (card.isCongeAm &&
|
||||||
card.statut == CarteStatut.refusee &&
|
card.statut == CarteStatut.refusee &&
|
||||||
card.motifRefus != null) ...[
|
card.motifRefus != null) ...[
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
'Motif : ${card.motifRefus}',
|
'Motif : ${card.motifRefus}',
|
||||||
maxLines: 4,
|
softWrap: true,
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: GoogleFonts.merriweather(
|
style: GoogleFonts.merriweather(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
|
|||||||
Reference in New Issue
Block a user